您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Сортировка друзей по группам, заметки на pl_info
// ==UserScript== // @name hwmFriendsTabs // @author Tamozhnya1 // @namespace Tamozhnya1 // @description Сортировка друзей по группам, заметки на pl_info // @version 1.2 // @include https://*.heroeswm.ru/home.php // @include https://*.heroeswm.ru/friends.php // @include https://*.lordswm.com/home.php // @include https://*.lordswm.com/friends.php // @include *heroeswm.ru/pl_info.php* // @include *lordswm.com/pl_info.php* // @license MIT // ==/UserScript== const playerIdMatch = document.cookie.match(/pl_id=(\d+)/); if(!playerIdMatch) { return; } const PlayerId = playerIdMatch[1]; addStyle(` .tablinks { display: flex; flex-wrap: wrap; flex-direction: row; } .tablink { background-color: #555; color: white; border: none; outline: none; cursor: pointer; padding: 7px 8px; font-size: 10pt; width: auto; } .tablink:hover { background-color: #777; } .tabcontent { padding: 20px 20px; height: 100%; } `); const isEn = document.documentElement.lang == "en"; const isNewPersonPage = document.querySelector("div#hwm_no_zoom") ? true : false; main(); function main() { if(location.pathname == "/pl_info.php") { const viewingPlayerId = getUrlParamValue(location.href, "id"); if(viewingPlayerId != PlayerId) { const container = document.querySelector("table.wblight > tbody > tr > td:nth-child(2)"); container.align = "left"; const playerInfoInput = createElement("input", { type: "text", style: "width: 150px;", value: getValue(`PlayerInfo${viewingPlayerId}`, ""), title: isEn ? "Notes" : "Заметки" }); playerInfoInput.addEventListener("change", function() { setValue(`PlayerInfo${viewingPlayerId}`, this.value); }) container.insertAdjacentElement("afterbegin", playerInfoInput); const resourcesTable = container.querySelector("table"); if(resourcesTable) { resourcesTable.style.display = "inline-table"; resourcesTable.style.verticalAlign = "bottom"; } } return; } //deletePlayerValue("FriendsGroups"); if(!getPlayerValue("FriendsGroups")) { setPlayerValue("FriendsGroups", JSON.stringify([isEn ? "Friends" : "Друзья", isEn ? "Familiar" : "Знакомые", isEn ? "Teachers" : "Учителя", isEn ? "Smiths" : "Кузнецы", isEn ? "Crafters" : "Крафтеры", isEn ? "Celebrities" : "Знаменитости", isEn ? "Clan" : "Клан", isEn ? "Enemies" : "Враги"])) } drawFriendsTabs(); } function drawFriendsTabs() { let friendsContainer; let friendsRefs; if(location.pathname == "/home.php") { const friendsCaption = Array.from(document.querySelectorAll("a[href='friends.php']")).find(x => x.innerHTML.includes(isEn ? "Friends online" : "Друзья в игре")); if(!friendsCaption) { return; } if(isNewPersonPage) { friendsContainer = getParent(friendsCaption, "div", 2); } else { const friendsCaptionTr = friendsCaption.closest("tr"); const friendsTr = friendsCaptionTr.nextElementSibling; friendsContainer = friendsTr.firstChild; } friendsRefs = Array.from(friendsContainer.querySelectorAll("a[href^='pl_info.php']")); } if(location.pathname == "/friends.php") { const mainFriendsTable = document.querySelector("form[name=f] table"); mainFriendsTable.width = ""; mainFriendsTable.style.width = "auto;" friendsRefs = Array.from(mainFriendsTable.querySelectorAll("a[href^='pl_info.php']")); const mainFriendsRow = document.querySelector("form[name=f]").closest("table").rows[0]; mainFriendsRow.cells[0].style = "width: 30%;"; friendsContainer = addElement("td", mainFriendsRow, { style: `height: 100%;` }); } friendsRefs.forEach(x => x.addEventListener("dragstart", function(e) { e.dataTransfer.setData("friendId", getUrlParamValue(e.target.href, "id")); })); let friendsGroupsContainer = document.querySelector("div#friendsGroupsContainer"); if(!friendsGroupsContainer) { friendsGroupsContainer = addElement("div", friendsContainer, { id: "friendsGroupsContainer", style: `position: relative; width: 100%; height: 100%; vertical-align: top;` }); } else { friendsGroupsContainer.innerHTML = ""; } const tabNames = JSON.parse(getPlayerValue("FriendsGroups")); if(parseInt(getPlayerValue("CurrentFriendsTab", 0)) > tabNames.length - 1) { setPlayerValue("CurrentFriendsTab", 0); } //console.log(tabNames) const buttonsContainer = addElement("div", friendsGroupsContainer, { class: "tablinks" }); tabNames.forEach((tabName, tabIndex) => { const button = addElement("button", buttonsContainer, { id: `showFriendsTabButton${tabIndex}`, class: "tablink", draggable: true, innerHTML: tabName }); button.addEventListener("click", function() { showTab(tabIndex); }); button.addEventListener("dragover", function(e) { e.preventDefault(); }); button.addEventListener("drop", function(e) { e.preventDefault(); if(e.dataTransfer.getData("friendId")) { addFiendToGroup(tabIndex, e.dataTransfer.getData("friendId")); // Принесли сюда друга } if(e.dataTransfer.getData("tabIndex")) { swapGroups(tabIndex, parseInt(e.dataTransfer.getData("tabIndex"))); // Принесли сюда другую закладку } }); button.addEventListener("dragstart", function(e) { e.dataTransfer.setData("tabIndex", tabIndex); }); }); const button = addElement("button", buttonsContainer, { class: "tablink", innerHTML: "+", title: isEn ? "Add group" : "Добавить группу" }); button.addEventListener("click", function() { const newTabNameInput = document.getElementById("newTabNameInput"); newTabNameInput.style.display = (newTabNameInput.style.display == "" ? "none" : ""); newTabNameInput.focus(); }); const newTabNameInput = addElement("input", button, { id: "newTabNameInput", type: "text", style: "display: none;" }); newTabNameInput.addEventListener("change", function() { addFriendsGroup(this.value); }); newTabNameInput.addEventListener("click", function(e) { e.stopPropagation(); }); const friendsGroupContainer = addElement("div", friendsGroupsContainer, { id: `friendsGroupContainer`, class: "tabcontent" }); friendsGroupContainer.addEventListener("dragover", function(e) { e.preventDefault(); }); friendsGroupContainer.addEventListener("drop", function(e) { e.preventDefault(); addFiendToGroup(undefined, e.dataTransfer.getData("friendId")); }); const basketDiv = addElement("div", friendsGroupsContainer, { style: "position: absolute; right: 0; bottom: 0;" }); const basket = addElement("img", basketDiv, { src: "https://dcdn.heroeswm.ru/i/artifacts/other/treasure.png", title: "Корзина", style: "width: 50px; height: 50px;" }); basket.addEventListener("dragover", function(e) { e.preventDefault(); }); basket.addEventListener("drop", function(e) { e.preventDefault(); e.stopPropagation(); deleteFriendsGroup(e.dataTransfer.getData("tabIndex"), e.dataTransfer.getData("friendId")); }); showTab(); } function swapGroups(tabIndex, newTabIndex) { const tabNames = JSON.parse(getPlayerValue("FriendsGroups")); [tabNames[tabIndex], tabNames[newTabIndex]] = [tabNames[newTabIndex], tabNames[tabIndex]]; setPlayerValue("FriendsGroups", JSON.stringify(tabNames)); const group1 = getPlayerValue(`FriendsGroup${tabIndex}`, "[]"); const group2 = getPlayerValue(`FriendsGroup${newTabIndex}`, "[]"); setPlayerValue(`FriendsGroup${tabIndex}`, group2); setPlayerValue(`FriendsGroup${newTabIndex}`, group1); setPlayerValue("CurrentFriendsTab", tabIndex); drawFriendsTabs(); } function showTab(tabIndex = parseInt(getPlayerValue("CurrentFriendsTab", 0))) { setPlayerValue("CurrentFriendsTab", tabIndex); const friendsGroupContainer = document.getElementById("friendsGroupContainer"); Array.from(friendsGroupContainer.querySelectorAll("div[name=friendRefContainer]")).forEach(x => x.remove()); Array.from(document.getElementsByClassName("tablink")).forEach(x => x.style.backgroundColor = ""); const color = `hsl(${Math.random() * 360}, 100%, 75%)`; document.querySelector("div#friendsGroupsContainer").style.backgroundColor = color; document.querySelector(`#showFriendsTabButton${tabIndex}`).style.backgroundColor = color; const group = JSON.parse(getPlayerValue(`FriendsGroup${tabIndex}`, "[]")); removeArrayEmptyEntries(group); //console.log(group); setPlayerValue(`FriendsGroup${tabIndex}`, JSON.stringify(group)); const friendNotes = JSON.parse(getPlayerValue("friendNotes", "{}")); for(const groupItem of group) { const mainRef = document.querySelector(`a[href='pl_info.php?id=${groupItem}']`); if(mainRef) { //console.log((mainRef.querySelector("b") || mainRef).innerText); const refDiv = addElement("div", friendsGroupContainer, { name: "friendRefContainer" }); const a = addElement("a", refDiv, { href: `pl_info.php?id=${groupItem}` }); addElement("b", a, {innerHTML: (mainRef.querySelector("b") || mainRef).innerText}); a.addEventListener("dragstart", function(e) { e.dataTransfer.setData("tabIndex", tabIndex); e.dataTransfer.setData("friendId", groupItem); }); const notesInput = addElement("input", refDiv, { type: "text", value: friendNotes[groupItem] || "", title: isEn ? "Notes" : "Заметки", style: `display: inline-block; width: ${isNewPersonPage ? 200 : 400}px;` }); notesInput.addEventListener("change", function() { savePlayerNote(groupItem, this.value); }); } } } function savePlayerNote(playerId, note) { const friendNotes = JSON.parse(getPlayerValue("friendNotes", "{}")); friendNotes[playerId] = note; setPlayerValue("friendNotes", JSON.stringify(friendNotes)); } function addFiendToGroup(tabIndex, friendId) { tabIndex = tabIndex || parseInt(getPlayerValue("CurrentFriendsTab", 0)); friendId = parseInt(friendId); const group = JSON.parse(getPlayerValue(`FriendsGroup${tabIndex}`, "[]")); if(!group.includes(friendId)) { group.push(friendId); setPlayerValue(`FriendsGroup${tabIndex}`, JSON.stringify(group)); drawFriendsTabs(); } } function addFriendsGroup(name) { const tabNames = JSON.parse(getPlayerValue("FriendsGroups")); if(name && !tabNames.includes(name)) { tabNames.push(name); setPlayerValue("FriendsGroups", JSON.stringify(tabNames)); drawFriendsTabs(); } } function deleteFriendsGroup(tabIndex, friendId) { tabIndex = parseInt(tabIndex); friendId = parseInt(friendId); console.log(`tabIndex: ${tabIndex}, friendId: ${friendId}`); if(friendId) { const group = JSON.parse(getPlayerValue(`FriendsGroup${tabIndex}`, "[]")); removeArrayValue(group, friendId); console.log(group) setPlayerValue(`FriendsGroup${tabIndex}`, JSON.stringify(group)); } else { const tabNames = JSON.parse(getPlayerValue("FriendsGroups")); for(let i = tabIndex; i < tabNames.length - 1; i++) { setPlayerValue(`FriendsGroup${i}`, getPlayerValue(`FriendsGroup${i + 1}`, "[]")); } deletePlayerValue(`FriendsGroup${tabNames.length - 1}`); tabNames.splice(tabIndex, 1); setPlayerValue("FriendsGroups", JSON.stringify(tabNames)); setPlayerValue("CurrentFriendsTab", 0); } drawFriendsTabs(); } // API function getParent(element, parentType, number = 1) { if(!element) { return; } let result = element; let foundNumber = 0; while(result = result.parentNode) { if(result.nodeName.toLowerCase() == parentType.toLowerCase()) { foundNumber++; if(foundNumber == number) { return result; } } } } 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 addStyle(css) { addElement("style", document.head, { type: "text/css", innerHTML: css }); } function getValue(key, defaultValue) { return localStorage[key] || defaultValue; }; function setValue(key, value) { localStorage[key] = value; }; function deleteValue(key) { return delete localStorage[key]; }; function listValues() { return Object.keys(localStorage); } function getPlayerValue(key, defaultValue) { return localStorage[`${key}${PlayerId}`] || defaultValue; }; function setPlayerValue(key, value) { localStorage[`${key}${PlayerId}`] = value; }; function deletePlayerValue(key) { return delete localStorage[`${key}${PlayerId}`]; }; function getPlayerBool(valueName, defaultValue = false) { return getBool(valueName + PlayerId, defaultValue); } function getBool(valueName, defaultValue = false) { const value = getValue(valueName); if(value != undefined) { if(typeof(value) == "string") { return value == "true"; } if(typeof(value) == "boolean") { return value; } } return defaultValue; } function getRequest(url, overrideMimeType = "text/html; charset=windows-1251") { return new Promise((resolve, reject) => { GM.xmlHttpRequest({ method: "GET", url: url, overrideMimeType: overrideMimeType, onload: function(response) { resolve((new DOMParser).parseFromString(response.responseText, "text/html")); }, onerror: function(error) { reject(error); } }); }); } function getUrlParamValue(url, paramName) { return (new URLSearchParams(url.split("?")[1])).get(paramName); } function removeArrayValue(array, value) { const index = array.indexOf(value); if(index > -1) { array.splice(index, 1); } } function removeArrayEmptyEntries(array) { let found = true; while(found) { const index = array.findIndex(x => !x); if(index > -1) { array.splice(index, 1); } else { found = false; } } }