// ==UserScript==
// @name hwmSetsMaster
// @author Tamozhnya1
// @namespace Tamozhnya1
// @description Меню наборов армии, навыков и оружия. Смена фракции.
// @version 7.9
// @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_listValues
// @grant GM_setValue
// @license MIT
// ==/UserScript==
const playerIdMatch = document.cookie.match(/pl_id=(\d+)/);
if(playerIdMatch) {
var PlayerId = playerIdMatch[1];
}
const windowObject = window.wrappedJSObject || unsafeWindow;
const elementType = { div: "div", a: "a", li: "li", table: "table", center: "center", input: "input", td: "td" };
const Strings = {
"ru": {
Army: ustring("Армия"),
Save: ustring("Сохранить"),
Add: ustring("Добавить"),
AddCurrent: ustring("Добавить текущий"),
SetName: ustring("Наименование набора"),
Delete: ustring("Удалить"),
Talents: ustring("Навыки"),
Weapon: ustring("Оружие"),
RemoveAll: ustring("Снять все"),
EnterJpg: "enter0.jpg",
SignInTitle: "Войти",
Castle: "Замок",
Task: ustring("Задание"),
Apply: ustring("Применить"),
EnterButtonValue: ustring("ВОЙТИ")
},
"en": {
Army: "Army",
Save: "Save",
Add: "Add",
AddCurrent: "Add current",
SetName: "Set name",
Delete: "Delete",
Talents: "Talents",
Weapon: "Weapon",
RemoveAll: "Un-equip all",
EnterJpg: "enter0_eng.jpg",
SignInTitle: "Sign in",
Castle: "Castle",
Task: "Task",
Apply: "Apply",
EnterButtonValue: "ENTER"
}
};
const LocalizedString = Strings[document.documentElement.lang || "ru"];
let userName;
let currentFaction;
const isMobileInterface = document.querySelector("div#btnMenuGlobal") ? true : false;
const isMobileDevice = mobileCheck();
const isNewInterface = document.querySelector("#main_top_table") ? false : true;
ensureGmMethods();
CalculateUserNameAndFaction();
/************************************************************************************************************/
const weaponSetsPreferences = {
menuTitle: LocalizedString.Weapon,
setReferencePage: "inventory.php",
sets: new Array(),
menuItems: {},
currentMenuItem: undefined,
refreshingPages: "home.php;inventory.php;pl_info.php",
refreshingConditions: function() {
if(/map.php/.test(location.href)) {
const bolds = document.querySelectorAll("b");
for(const bold of bolds) {
if(bold.innerText.includes(LocalizedString.Task)) {
return true;
}
}
const neut_right_block = document.querySelector("#neut_right_block");
if(neut_right_block) {
return true;
}
}
return false;
},
initSetsApplyAction: function() {
this.sets.length = 0;
this.sets.push({ number: 0, name: LocalizedString.RemoveAll, method: "GET", url: "inventory.php?all_off=100" });
const weaponSets = JSON.parse(GM_getValue(`WeaponSets${PlayerId}`, "{}"));
for(const setNumber of Object.keys(weaponSets)) {
this.sets.push({ number: setNumber, name: weaponSets[setNumber], method: "GET", url: `inventory.php?all_on=${setNumber}`, headers: null });
}
},
getCurrentSetName: function() { return `WeaponSet${PlayerId}`; },
init: function() {
if(/inventory.php/.test(location.href)) {
let undressDiv = document.querySelector("div[id ='undress_all_div']");
addSetChangerListener(undressDiv, this, 0);
let setDivs = document.querySelectorAll("div[set_div_id]"); // Если setDivs.length = 0, то ничего не делаем - мы в заявке на бой
if(setDivs.length > 0) {
const weaponSets = {};
for(const setDiv of setDivs) {
let setNumber = setDiv.getAttribute("set_div_id");
if(setDiv.hasAttribute("onclick")) {
weaponSets[setNumber] = setDiv.innerText;
addSetChangerListener(setDiv, this, setNumber);
}
}
GM_setValue(`WeaponSets${PlayerId}`, JSON.stringify(weaponSets));
}
}
this.findSetChangersAndAddListener();
},
findSetChangersAndAddListener: function() {
let setRefs = document.querySelectorAll("a[href^='inventory.php?all_off=100']");
for(const setRef of setRefs) {
addSetChangerListener(setRef, this, 0);
}
setRefs = document.querySelectorAll("a[href*='inventory.php?all_on=']");
for(const weaponSetReference of setRefs) {
let setNumber = weaponSetReference.getAttribute("href").split("all_on=")[1];
addSetChangerListener(weaponSetReference, this, setNumber);
}
}
};
/***********************************************************************************************************/
const skillSetsPreferences = {
menuTitle: LocalizedString.Talents,
setReferencePage: "skillwheel.php",
sets: new Array(),
menuItems: {},
currentMenuItem: undefined,
refreshingPages: "skillwheel.php;pl_info.php",
initSetsApplyAction: function () {
const setRefs = document.querySelectorAll("a[href^='skillwheel.php?setuserperk']");
this.sets.length = 0;
let i = 0;
for(const setRef of setRefs) {
this.sets.push({ number: i, name: setRef.innerHTML, method: "GET", url: setRef.href });
addSetChangerListener(setRef, this, i);
i++;
}
},
getCurrentSetName: function() { return userName + currentFaction + "currentSkillSet"; }
};
/************************************************************************************************************/
const armySetsPreferences = {
menuTitle: LocalizedString.Army,
setReferencePage: "army.php",
sets: new Array(),
savedArmyInfos: new Array(),
menuItems: {},
currentMenuItem: undefined,
refreshingPages: "home.php;army.php;pl_info.php",
setsTable: null,
initSetsApplyAction: function () {
this.sets.length = 0;
let i = 0;
for(const savedArmyInfo of this.savedArmyInfos) {
this.sets.push(this.getSet(savedArmyInfo));
}
},
getSet: function(savedArmyInfo) {
let armySetTooltip = "";
let postData = "";
let j = 0;
for(const armyUnitAmount of savedArmyInfo.army) {
armySetTooltip += (armyUnitAmount == "" ? "0" : armyUnitAmount) + "+";
postData = `countv${++j}=${(armyUnitAmount == "" ? "0" : armyUnitAmount)}${(postData == "" ? "" : "&") + postData}`;
}
return {
number: parseInt(savedArmyInfo.setId),
name: savedArmyInfo.name,
title: armySetTooltip.substring(0, armySetTooltip.length - 1),
method: "POST",
url: "army_apply.php",
data: postData,
contentType: "application/x-www-form-urlencoded"
}
},
getCurrentSetName: function() { return userName + currentFaction + "currentArmySet"; },
init: function() {
let savedSetIdsStr = GM_getValue(userName + currentFaction + "savedArmySetIds");
let setIds = new Array();
if(savedSetIdsStr) {
setIds = savedSetIdsStr.split("|");
}
this.savedArmyInfos.length = 0;
for(const setId of setIds) {
if(setId == "") {
continue;
}
let setStr = GM_getValue(userName + currentFaction + "savedArmySet" + setId);
if(!setStr) {
continue;
}
let savedSetParams = setStr.split("|");
let savedArmyInfo = {
setId: setId,
name: savedSetParams[7],
fraction: savedSetParams[8],
army: new Array()
};
for(let j = 0; j < 7; j++) {
savedArmyInfo.army[j] = savedSetParams[j];
}
this.savedArmyInfos.push(savedArmyInfo);
}
if(/\/army.php/.test(location.href)) {
this.drawSetsTable();
}
},
drawSetsTable: function () {
const isInit = this.setsTable ? false : true;
let container;
if(isInit) {
const hwm_for_zoom = document.getElementById("hwm_for_zoom");
container = document.body;
if(!isMobileInterface) {
container = addElement("center", hwm_for_zoom);
}
const tableStyle = "background-color: #959595; border: 1px solid #f5c137; table-layout: fixed;" + (isMobileInterface ? "margin: 0 0 0 50px;" : "");
this.setsTable = addElement(elementType.table, container, { style: tableStyle });
} else {
this.setsTable.innerHTML = "";
container = this.setsTable.parentNode;
}
const cellWidths = [100, 60, 60, 60, 60, 60, 60, 60, 10, 10];
for(const cellWidth of cellWidths) {
this.setsTable.innerHTML += `<col style="width: ${cellWidth}px;" />`;
}
this.drawTableHeader();
for(const savedArmyInfo of this.savedArmyInfos) {
this.drawSetRow(savedArmyInfo);
}
if(isInit) {
const saveButton = addElement(elementType.input, container, { type: "button", value: LocalizedString.Save, style: isMobileInterface ? "margin: 0 0 0 50px;" : "" });
saveButton.addEventListener("click", this.saveSets);
const addCurrentButton = addElement(elementType.input, container, { type: "button", value: LocalizedString.AddCurrent });
addCurrentButton.addEventListener("click", this.addCurrentSet);
}
},
drawTableHeader: function () {
if(!this.setsTable) {
return;
}
let cellStyle = "border: 1px solid #f5c137; overflow: hidden;";
let units = windowObject.obj;
let tr = addElement("tr", this.setsTable);
addElement(elementType.td, tr, { innerHTML: LocalizedString.SetName.replace(/ /g, "<br>").replace(/-/g, "-<br>"), style: "font-weight: bold; font-size: 8pt; text-align: center; border: 1px solid #f5c137; overflow: hidden;" }); // ; overflow: hidden
for(let i = 1; i <= 7; i++) {
addElement(elementType.td, tr, { innerHTML: units[i]['name'].replace(/ /g, "<br>").replace(/-/g, "-<br>"), style: "font-weight: bold; font-size: 8pt; text-align: center; border: 1px solid #f5c137; overflow: hidden;", onClick: `ChangeSlider(event, ${i}, 0);` });
}
addElement(elementType.td, tr, { style: cellStyle });
addElement(elementType.td, tr, { style: cellStyle });
},
drawSetRow: function (savedArmyInfo, isNew) {
isNew = isNew || false;
let cellStyle = "border: 1px solid #f5c137; overflow: hidden;";
if(!this.setsTable) {
return;
}
let tr = addElement("tr", this.setsTable, { setId: savedArmyInfo.setId });
let td = addElement(elementType.td, tr, { style: cellStyle });
let input = addElement(elementType.input, td, { value: savedArmyInfo.name, onfocus: `this.select();`, style: "width: 97px;" }); //, style: "overflow: hidden;"
for(let i = 0; i < savedArmyInfo.army.length; i++) {
td = addElement(elementType.td, tr, { style: cellStyle });
input = addElement(elementType.input, td, { value: savedArmyInfo.army[i], onfocus: `ChangeSlider(event, ${i + 1}, 0); this.select();`, type: "number", style: "min-width: 47px; width: 98%; text-align: right;" });
}
td = addElement(elementType.td, tr, { style: cellStyle });
let delButton = addElement(elementType.input, td, { type: "button", value: "x", title: LocalizedString.Delete });
delButton.addEventListener("click", this.deleteSet);
td = addElement(elementType.td, tr, { style: cellStyle });
if(!isNew) {
let applyButton = addElement(elementType.input, td, { type : "button", value : "v", title : LocalizedString.Apply });
applyButton.addEventListener("click", function() { armySetsPreferences.saveSets(); applySet(null, armySetsPreferences, armySetsPreferences.getSet(savedArmyInfo)); }, false);
}
},
saveSets: function () {
let table = armySetsPreferences.setsTable;
let setIdsStr = "";
for(let i = 1; i < table.rows.length; i++) {
let setStr = "";
let row = table.rows[i];
let setId = row.getAttribute("setId");
setIdsStr = setIdsStr + "|" + setId;
for(let j = 1; j <= 7; j++) {
setStr = setStr + "|" + row.cells[j].firstChild.value;
}
setStr = setStr + "|" + row.cells[0].firstChild.value + "|";
setStr = setStr.substr(1);
GM_setValue(userName + currentFaction + "savedArmySet" + setId, setStr);
}
if(setIdsStr != "") {
GM_setValue(userName + currentFaction + "savedArmySetIds", setIdsStr.substr(1));
} else {
GM_deleteValue(userName + currentFaction + "savedArmySetIds");
GM_deleteValue(armySetsPreferences.getCurrentSetName());
}
let armySetIdRegExp = new RegExp(userName + currentFaction + "savedArmySet" + '(\\d+)');
let allStorageKeys = GM_listValues();
let allStorageKeysCount = allStorageKeys.length;
for(let i = allStorageKeysCount; i--; ) {
let armySetId = armySetIdRegExp.exec(allStorageKeys[i]);
if(armySetId && (setIdsStr == "" || !setIdsStr.match(armySetId[1])) ) {
GM_deleteValue(allStorageKeys[i]);
}
}
},
addCurrentSet: function () {
let units = windowObject.obj;
let savedArmyInfo = {
setId : (new Date()).getTime(),
name : "",
army : [units[1]['nownumberd'], units[2]['nownumberd'], units[3]['nownumberd'], units[4]['nownumberd'], units[5]['nownumberd'], units[6]['nownumberd'], units[7]['nownumberd']]
};
armySetsPreferences.drawSetRow(savedArmyInfo, true);
},
deleteSet: function () {
let table = this.parentNode.parentNode.parentNode;
let row = this.parentNode.parentNode;
table.removeChild(row);
}
};
/************************************************************************************************************/
const factionsPreferences = {
menuTitle: LocalizedString.Castle,
setReferencePage: "castle.php",
sets: new Array(),
menuItems: {},
currentMenuItem: undefined,
availableCastleNames: "availableCastleNames",
refreshingPages: "home.php;army.php;pl_info.php;castle.php;inventory.php;skillwheel.php",
userCastleSign: undefined,
userCastleSignName: "userCastleSign",
refreshingConditions: function() {
return false;
},
initSetsApplyAction: function() {
let serializedCastlesInfo = GM_getValue(userName + this.availableCastleNames);
if(serializedCastlesInfo) {
let castles = serializedCastlesInfo.split("&");
this.sets.length = 0;
for(let castle of castles) {
const castleParts = castle.split("=");
const setInfo = { number: castleParts[1], name: castleParts[0], method: "GET" };
if(this.userCastleSign) {
setInfo.url = `castle.php?change_clr_to=${castleParts[1]}&sign=${this.userCastleSign}`;
}
this.sets.push(setInfo);
}
}
},
getCurrentSetName: function() { return userName + "currentCastle"; },
init: function () {
this.initCastlesList();
this.userCastleSign = GM_getValue(userName + this.userCastleSignName);
this.findSetChangersAndAddListener();
},
initCastlesList: function () {
if(!/castle.php/.test(location.href)) {
return;
}
let castleNamesDivs = document.querySelectorAll("div.castle_faction_div_inside");
let serializedCastlesInfo = "";
for(let castleNamesDivIndex = 0; castleNamesDivIndex < castleNamesDivs.length; castleNamesDivIndex++) {
let castleNameDiv = castleNamesDivs[castleNamesDivIndex];
let castleName = castleNameDiv.getAttribute("hint");
let castleSelectRef = castleNameDiv.firstChild.getAttribute("href");
let castleNumber = castleSelectRef.split("=")[1];
serializedCastlesInfo = serializedCastlesInfo + (serializedCastlesInfo == "" ? "" : "&") + castleName + "=" + castleNumber;
}
GM_setValue(userName + this.availableCastleNames, serializedCastlesInfo);
let castle_yes_no_dialogDiv = document.querySelector("div.castle_yes_no_dialog");
if(castle_yes_no_dialogDiv) {
let changeCastleRef = castle_yes_no_dialogDiv.querySelector("a[href*='castle.php?change_clr_to']");
if(changeCastleRef) {
let userCastleSign = changeCastleRef.getAttribute("href").split("?")[1].split("&")[1].split("=")[1];
GM_setValue(userName + this.userCastleSignName, userCastleSign);
}
}
},
findSetChangersAndAddListener: function() {
let setRefs = document.querySelectorAll("a[href*='castle.php?change_clr_to']");
for(let i = 0; i < setRefs.length; i++) {
let changeCastleRef = setRefs[i];
let setNumber = changeCastleRef.getAttribute("href").split("?")[1].split("&")[0].split("=")[1];
addSetChangerListener(changeCastleRef, this, setNumber);
}
},
setChanged: function(newSetNumber) {
currentFaction = "r" + newSetNumber + "_";
GM_setValue(userName + "currentFaction", currentFaction);
main();
}
};
/************************************************************************************************************/
const preferences = [weaponSetsPreferences, skillSetsPreferences, armySetsPreferences, factionsPreferences];
const isHeartOnPage = document.querySelector("canvas#heart") || document.querySelector("div#heart_js_mobile");
main();
function mobileCheck() {
let check = false;
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
return check;
};
function main() {
//console.log([userName, currentFaction]);
if(isHeartOnPage && userName && currentFaction) {
createMenu();
window.addEventListener("resize", function() { createMenu(true); });
}
}
function getMenuAnchorElement() {
// const homeRefs = document.querySelectorAll("a[href='home.php']");
// console.log(`homeRefs: ${homeRefs.length}`);
const menuPanel = document.querySelector("div.sh_MenuPanel") || document.querySelector("#main_top_table") || document;
if(menuPanel) {
const homeRef = menuPanel.querySelector("a[href='home.php']");
if(isNewInterface) {
//homeRef.parentNode.addEventListener("resize", function() { createMenu(true); });
return homeRef.parentNode;
} else {
const result = homeRef.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode?.parentNode;
if(!result) {
result = homeRef.parentNode;
}
return result;
}
}
}
function getTextWidth(text, font) {
const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas")); // re-use canvas object for better performance
const context = canvas.getContext("2d");
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
function getCssStyle(element, prop) { return window.getComputedStyle(element, null).getPropertyValue(prop); }
function getCanvasFont(el = document.body) {
const fontWeight = getCssStyle(el, 'font-weight') || 'normal';
const fontSize = getCssStyle(el, 'font-size') || '16px';
const fontFamily = getCssStyle(el, 'font-family') || 'Times New Roman';
return `${fontWeight} ${fontSize} ${fontFamily}`;
}
function getOrCreateAndResizeDropdown(baseElement, style) {
const dropdownId = `${baseElement.id}Dropdown`;
let dropdown = document.getElementById(dropdownId);
if(!dropdown) {
dropdown = addElement("div", document.body, { id: dropdownId, style: `position: absolute; z-index: ${baseElement.style.zIndex};` + (style || "") });
if(isMobileDevice) {
baseElement.addEventListener("click", function() {
dropdown.style.display = dropdown.style.display == "none" ? "block" : "none";
if(dropdown.style.display == "block") {
const dropdowns = document.querySelectorAll("div[id$=Dropdown]");
for(const dropdown of dropdowns) {
if(dropdown.id != dropdownId) {
dropdown.style.display = "none";
}
}
}
}, false);
} else {
let hideTimer;
const dropdownTimeout = 100;
baseElement.addEventListener("mouseenter", function() { clearTimeout(hideTimer); if(dropdown.style.display == "none") { setTimeout(function() { dropdown.style.display = "block"; }, dropdownTimeout); } }, false);
baseElement.addEventListener("mouseleave", function() { hideTimer = setTimeout(function() { dropdown.style.display = "none"; }, dropdownTimeout); }, false);
dropdown.addEventListener("mouseenter", function() { clearTimeout(hideTimer); }, false);
dropdown.addEventListener("mouseleave", function() { hideTimer = setTimeout(function() { dropdown.style.display = "none"; }, dropdownTimeout); }, false);
}
}
const baseElementRect = baseElement.getBoundingClientRect();
dropdown.style.top = `${baseElementRect.bottom + window.scrollY + 1}px`;
dropdown.style.left = `${baseElementRect.left}px`;
return dropdown;
}
function createMenu(isResize) {
const menuAnchor = getMenuAnchorElement();
if(!menuAnchor) {
return;
}
const anchorRect = menuAnchor.getBoundingClientRect();
//console.log(anchorRect);
const borderWidth = isNewInterface ? 1 : 2;
const menuItemHeight = anchorRect.height - borderWidth * 2;
const menuItemLineHeight = menuItemHeight - borderWidth;
const menuItemTop = anchorRect.top + window.scrollY;
const foreColor = "#f5c137";
const backgroundColor = isNewInterface ? "linear-gradient(to top, #09203f 0%, #537895 100%)" : (document.querySelector("img[src*='i/top_ny']") ? "#003399" : "#6b6b69");
const zIndex = location.pathname == "/photo_pl_photos.php" ? "0" : "100";
let currentMenuItemLeft = anchorRect.left - borderWidth - 1;
for(let i = preferences.length - 1; i >= 0; i--) {
const currentPreferences = preferences[i];
if(!isResize && currentPreferences.init) {
currentPreferences.init();
}
currentPreferences.initSetsApplyAction();
const mainMenuItemId = `SetsMenuItem${i}`;
let mainMenuItem = document.getElementById(mainMenuItemId);
if(!mainMenuItem) {
const menuHeaderStyle = `font-size: 9pt; position: absolute; border-radius: 5px; background: ${backgroundColor}; color: ${foreColor}; border: ${borderWidth}px solid ${foreColor}; padding: 0 3px 0 3px; font-weight: bold; text-align: center; z-index: ${zIndex};`;
mainMenuItem = addElement("div", document.body, { id: mainMenuItemId, style: menuHeaderStyle });
if(isMobileDevice) {
addElement("span", mainMenuItem, { innerHTML: currentPreferences.menuTitle, style: `color: ${foreColor}; text-decoration: none;` });
} else {
addElement("a", mainMenuItem, { innerHTML: currentPreferences.menuTitle, href: currentPreferences.setReferencePage, style: `color: ${foreColor}; text-decoration: none;` });
}
}
mainMenuItem.style.height = `${menuItemHeight}px`;
mainMenuItem.style.lineHeight = `${menuItemLineHeight}px`;
mainMenuItem.style.top = `${menuItemTop}px`;
const mainMenuItemRect = mainMenuItem.getBoundingClientRect();
currentMenuItemLeft -= mainMenuItemRect.width;
mainMenuItem.style.left = `${currentMenuItemLeft}px`;
const menuContent = getOrCreateAndResizeDropdown(mainMenuItem, `list-style-position: inside; color: ${foreColor}; padding: 2px 3px 2px 3px; white-space: nowrap; background: ${backgroundColor};`);
if(isResize) {
continue;
}
menuContent.style.display = "block"; // Перед заполнением покажем див для правильного определения его размеров (нужно, если он установлен в none)
menuContent.innerHTML = '';
let currentSetNumber = GM_getValue(currentPreferences.getCurrentSetName(), -1);
let maxClientWidth = menuContent.clientWidth;
for(const currentSet of currentPreferences.sets) {
const dropDownMenuItem = addElement("li", menuContent, { type: "disc", style: "text-align: left;" });
const currentSetReference = addElement("b", dropDownMenuItem, { innerHTML: currentSet.name, title: currentSet.title || "", style: `color: ${foreColor}; cursor: pointer;` });
if(currentSet.url) {
currentSetReference.addEventListener("click", function() { applySet(currentSetReference, currentPreferences, currentSet); }, false);
}
if(currentSet.number == currentSetNumber) {
markCurrent(currentSetReference, currentPreferences, currentSet.number);
}
currentPreferences.menuItems[currentSet.number] = currentSetReference;
let currentWidth = getTextWidth(currentSet.name, getCanvasFont(currentSetReference));
if(maxClientWidth < currentWidth) {
maxClientWidth = currentWidth;
}
}
menuContent.style.minWidth = `${(maxClientWidth + 25)}px`;
menuContent.style.display = "none";
}
}
function markCurrent(selectedMenuItem, currentPreferences, currentSetNumber) {
GM_setValue(currentPreferences.getCurrentSetName(), currentSetNumber);
if(selectedMenuItem) {
selectedMenuItem.style.color = '#0f0';
if (currentPreferences.currentMenuItem && currentPreferences.currentMenuItem != selectedMenuItem) {
currentPreferences.currentMenuItem.style.color = "#f5c137";
}
currentPreferences.currentMenuItem = selectedMenuItem;
}
}
function addSetChangerListener(htmlElement, currentPreferences, setNumber) {
htmlElement.addEventListener("click", function() { markCurrent(currentPreferences.menuItems[setNumber], currentPreferences, setNumber); }, false);
}
function applySet(selectedMenuItem, currentPreferences, currentSet) {
markCurrent(selectedMenuItem, currentPreferences, currentSet.number);
const originalText = selectedMenuItem ? selectedMenuItem.innerHTML : "";
if(selectedMenuItem) {
selectedMenuItem.innerHTML += " " + getLoadGif();
}
const request = new XMLHttpRequest();
request.open(currentSet.method, currentSet.url, true);
request.onreadystatechange = function () {
if(request.readyState == 2) {
request.abort();
if(selectedMenuItem) {
selectedMenuItem.innerHTML = originalText;
if(isMobileDevice) {
selectedMenuItem.parentNode.parentNode.style.display = "none";
}
}
if(typeof(currentPreferences.setChanged) == "function") {
currentPreferences.setChanged(currentSet.number);
}
if(currentPreferences.refreshingPages) {
let pages = currentPreferences.refreshingPages.split(';');
for(const page of pages) {
if(location.href.indexOf(page) > -1) {
window.location.reload();
}
}
}
if(currentPreferences.refreshingConditions && currentPreferences.refreshingConditions()) {
window.location.reload();
}
}
};
if(currentSet.contentType) {
request.setRequestHeader('Content-type', currentSet.contentType);
}
request.send(currentSet.data);
return false;
}
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 getLoadGif() {
return '<img border="0" align="absmiddle" height="11" src="data:image/gif;base64,' +
'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' +
'fySDhGYQdDWGQyUhADs=">';
}
function ensureGmMethods() {
if(!this.GM_getValue) {
this.GM_getValue = function(key, def) { return localStorage[key] || def; };
this.GM_setValue = function(key, value) { localStorage[key] = value; };
this.GM_deleteValue = function(key) { return delete localStorage[key]; };
}
if(!this.GM_listValues) {
this.GM_listValues = function() {
const values = [];
for(let key in localStorage) {
values.push(localStorage[key]);
}
return values;
}
}
}
function CalculateUserNameAndFaction() {
let enterButton = document.querySelector("input[src$='" + LocalizedString.EnterJpg + "']") || document.querySelector("input[value$='" + LocalizedString.SignInTitle + "']");
//console.log(enterButton);
if(/login.php$/.test(location.href)) {
enterButton = document.querySelector("input[value='" + LocalizedString.SignInTitle + "']");
}
let loginTextBox = document.querySelector("input[name='login']");
if(enterButton && loginTextBox) {
enterButton.addEventListener("click", function() { GM_setValue("UserName", loginTextBox.value + "_"); })
} else {
userName = GM_getValue("UserName");
if(/home.php/.test(location.href)) {
let userNameFromHomePage;
let playersInfos = document.querySelectorAll("a.pi");
for(const playersInfo of playersInfos) {
if(playersInfo.nextElementSibling && playersInfo.nextElementSibling.tagName == "A" && playersInfo.nextElementSibling.href.indexOf("castle.php?change_faction_dialog") > -1) {
userNameFromHomePage = playersInfo.querySelector("b").innerText + "_";
}
}
if(!userNameFromHomePage) {
console.log("UserName on home page not found");
}
if(userName && userName != userNameFromHomePage) {
console.log("Saved UserName not equal UserName on home page");
}
if(!userName) {
userName = userNameFromHomePage;
GM_setValue("UserName", userNameFromHomePage);
}
}
if(!userName) {
return;
}
userName = encodeURIComponent(userName);
let currentFactionNumber;
if(location.pathname == '/home.php') {
// for new home page
let currentFactionIconContainer = document.querySelector("div.home_css_pl_fract.show_hint");
if(!currentFactionIconContainer) {
currentFactionIconContainer = document.querySelector("a[href^='castle.php?change_faction_dialog']");
}
if(currentFactionIconContainer) {
let currentFactionIconImg = currentFactionIconContainer.querySelector("img");
currentFactionNumber = currentFactionIconImg.src.split("i/f/r")[1].split(".png")[0];
}
} else if(location.pathname=='/pl_info.php') {
let temp_nick = userName;
let temp_regexp = new RegExp(temp_nick.slice(0, -1)+'.\{30,150\}\\/i\\/f\\/(r\\d+)\\.png');
let frakPng = temp_regexp.exec( document.querySelector("body").innerHTML );
if(frakPng) {
currentFactionNumber = frakPng[1].substring(1);
}
} else if(location.pathname=='/castle.php') {
let selectedFactionImg = document.querySelector("div.castle_faction_div_inside2 img");
let selectedFactionImgName = selectedFactionImg.getAttribute("src");
let selectedFactionNumber = selectedFactionImgName.split("kukla_png/kukla")[1].split(".")[0]; //dcdn.heroeswm.ru/i/kukla_png/kukla5.png
let faction_listDiv = document.querySelector("div[id='faction_list']");
if(faction_listDiv.getAttribute("style").includes("display:none;")) {
currentFactionNumber = selectedFactionNumber;
}
}
if(currentFactionNumber) {
GM_setValue(userName + "currentCastle", currentFactionNumber);
GM_setValue(userName + "currentFaction", "r" + currentFactionNumber + "_");
}
currentFaction = GM_getValue(userName + "currentFaction");
}
}
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;
}