hwmAdvancedMenu

Расширенное меню

当前为 2023-12-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name hwmAdvancedMenu
  3. // @namespace Tamozhnya1
  4. // @author Tamozhnya1
  5. // @description Расширенное меню
  6. // @version 1.1
  7. // @include *heroeswm.ru/*
  8. // @include *lordswm.com/*
  9. // @exclude */rightcol.php*
  10. // @exclude */ch_box.php*
  11. // @exclude */chat*
  12. // @exclude */ticker.html*
  13. // @exclude */frames*
  14. // @exclude */brd.php*
  15. // @license MIT
  16. // ==/UserScript==
  17.  
  18. if(!this.GM_getValue) {
  19. this.GM_getValue = function(key, def) { return localStorage[key] || def; };
  20. this.GM_setValue = function(key, value) { localStorage[key] = value; };
  21. this.GM_deleteValue = function(key) { return delete localStorage[key]; };
  22. }
  23. const playerIdMatch = document.cookie.match(/pl_id=(\d+)/);
  24. if(!playerIdMatch) {
  25. return;
  26. }
  27. const PlayerId = playerIdMatch[1];
  28. const isEn = document.documentElement.lang == "en";
  29. const isNewInterface = document.querySelector("#main_top_table") ? false : true;
  30.  
  31. main();
  32. function main() {
  33. processHouses();
  34. processQuickLinks();
  35. // После рынка вставим ссылки на ресурсы, с задержкой в пол секунды
  36. const auctionRef = isNewInterface ? document.querySelector("div.sh_dd_container a[href='auction.php']") : getParent(document.querySelector("li > a[href='auction.php']"), "li");
  37. if(auctionRef) {
  38. let resourcesShowTimer;
  39. let resourcesShown = false;
  40. const resources = [ { type: "1", name: isEn ? 'Wood' : 'Древесина' }, { type: "2", name: isEn ? 'Ore' : 'Руда' }, { type: "3", name: isEn ? 'Mercury' : 'Ртуть' }, { type: "4", name: isEn ? 'Sulfur' : 'Сера' }, { type: "5", name: isEn ? 'Crystals' : 'Кристаллы' }, { type: "6", name: isEn ? 'Gems' : 'Самоцветы' } ];
  41. auctionRef.addEventListener("mouseover", function() { if(!resourcesShown) resourcesShowTimer = setTimeout(function() {
  42. const html = resources.reduce((t, x) => t + getMenuItemTemplate(`auction.php?cat=res&sort=0&type=${x.type}`, `  ${x.name}`), "");
  43. auctionRef.insertAdjacentHTML('afterend', html);
  44. resourcesShown = true;
  45. }, 500) } );
  46. auctionRef.addEventListener("mouseout", function() { clearTimeout(resourcesShowTimer); });
  47. }
  48. // После передачи ресурсов вставим основные ссылки персонажа
  49. const transferRef = isNewInterface ? document.querySelector("div.sh_dd_container a[href='transfer.php']") : getParent(document.querySelector("li > a[href='transfer.php']"), "li");
  50. if(transferRef) {
  51. const personalReferences = [
  52. { href: `el_transfer.php`, text: isEn ? 'Transfer elements' : 'Передача элементов' },
  53. { href: 'javascript:void(0);', text: "" },
  54. { href: `pl_info.php?id=${PlayerId}`, text: isEn ? 'Character' : 'Персонаж' },
  55. { href: `pl_transfers.php?id=${PlayerId}`, text: isEn ? 'Transfer log' : 'Протокол передач' },
  56. { href: `pl_warlog.php?id=${PlayerId}`, text: isEn ? 'Combat log' : 'Протокол боев' },
  57. { href: `pl_cardlog.php?id=${PlayerId}`, text: isEn ? 'Game log' : 'Протокол игр' },
  58. { href: `friends.php`, text: isEn ? 'Your friends' : 'Ваши друзья' },
  59. { href: `ephoto_albums.php`, text: isEn ? 'Your photos' : 'Ваш фотоальбом' },
  60. { href: 'javascript:void(0);', text: "" },
  61. { href: `logout.php?${Math.round( Math.random()* 100000 )}`, text: isEn ? 'Logout' : 'Выход' }
  62. ];
  63. const html = personalReferences.reduce((t, x) => t + getMenuItemTemplate(x.href, x.text), "");
  64. transferRef.insertAdjacentHTML('afterend', html);
  65. }
  66. // Расширение карты
  67. const mapMenuContainer = isNewInterface ? document.querySelector("div.sh_dd_container a[href='map.php?st=hs']") : getParent(document.querySelector("li > a[href='map.php?st=hs']"), "li");
  68. if(mapMenuContainer) {
  69. const housesInfo = JSON.parse(GM_getValue(`PlayerHouses${PlayerId}`, "{}"));
  70. let mapExtenders = Object.keys(housesInfo).map(x => ({ href: `house_info.php?id=${x}`, text: housesInfo[x].replace(" ", " ") }));
  71. // Арендованные дома. Берутся из скрипта Transporter
  72. for(let locationNumber = 1; locationNumber <= 27; locationNumber++) {
  73. const guestInfo = JSON.parse(GM_getValue(`GuestInfo${locationNumber}`, "{}"));
  74. for(const key in guestInfo) {
  75. mapExtenders = [...mapExtenders, { href: `house_info.php?id=${key}`, text: guestInfo[key].HostInfo, title: `до ${(new Date(guestInfo[key].ExpireDate)).toLocaleString()}` }];
  76. }
  77. }
  78. //
  79. mapExtenders = [...mapExtenders, { href: 'javascript:void(0);', text: "" }, { href: 'ecostat.php', text: isEn ? 'Economic statistics' : 'Эконом. статистика' }];
  80. const html = mapExtenders.reduce((t, x) => t + getMenuItemTemplate(x.href, x.text, x.title), "");
  81. //console.log(mapExtenders)
  82. mapMenuContainer.insertAdjacentHTML('afterend', html);
  83. }
  84. // Добавим форумов и дейли
  85. const forumsContainer = isNewInterface ? document.querySelector("div.sh_dd_container a[href='forum.php#t1']") : getParent(document.querySelector("li > a[href='forum.php#t1']"), "li");
  86. if(forumsContainer) {
  87. const forumExtenders = [
  88. { href: `forum_thread.php?id=${isEn ? '103' : '3'}`, text: isEn ? 'Ideas and suggestions' : 'Идеи и предложения' },
  89. { href: `forum_thread.php?id=${isEn ? '121' : '22'}`, text: isEn ? 'Smiths and Ench. services' : 'Услуги кузнецов и оруж.' },
  90. { href: 'javascript:void(0);', text: "" },
  91. { href: `${isEn ? 'http://daily.heroeswm.ru/newscom.php' : 'http://daily.heroeswm.ru/'}`, text: isEn ? 'HWM Daily ENG' : 'Геройская лента' }
  92. ];
  93. const html = forumExtenders.reduce((t, x) => t + getMenuItemTemplate(x.href, x.text), "");
  94. forumsContainer.insertAdjacentHTML('afterend', html);
  95. }
  96. // После чатов добавим быстрые ссылки
  97. const framesContainer = isNewInterface ? document.querySelector("div.sh_dd_container a[href='frames.php?room=4']") : getParent(document.querySelector("li > a[href='frames.php?room=4']"), "li");
  98. if(framesContainer) {
  99. //GM_deleteValue(`QuickLinks${PlayerId}`);
  100. let quickLinks = JSON.parse(GM_getValue(`QuickLinks${PlayerId}`, "[]")).filter(x => x.Name != "" && x.Refernce != "");
  101. if(quickLinks.length > 0) {
  102. quickLinks = [{ Refernce: "javascript:void(0);", Name: "" }, ...quickLinks];
  103. const html = quickLinks.reduce((t, x) => t + getMenuItemTemplate(x.Refernce, x.Name), "");
  104. framesContainer.insertAdjacentHTML('afterend', html);
  105. }
  106. }
  107. }
  108. function getMenuItemTemplate(href, text, title) { return !isNewInterface ? `<li>${text != "" ? `<a href='${href}'${!title ? "" : ` title='${title}'`}>${text}</a>` : "<hr>"}</li>` : `<a href='${href}'${!title ? "" : ` title='${title}'`} style='text-decoration:none;'><div${text == "" ? " style='padding: 0; height: 2px;'" : ""}>${text}</div></a>`; }
  109. function processHouses() {
  110. if(location.pathname == "/pl_info_realty.php" && getUrlParamValue(location.href, "id") == PlayerId) {
  111. const housesInfo = Array.from(document.querySelectorAll("a[href^='house_info.php']")).reduce((t, x) => ({...t, [getUrlParamValue(x.href, "id")]: getParent(x, "tr").cells[4].innerText }), {});
  112. //console.log(housesInfo);
  113. GM_setValue(`PlayerHouses${PlayerId}`, JSON.stringify(housesInfo));
  114. }
  115. }
  116. function processQuickLinks() {
  117. if(location.pathname == "/pers_navlinks.php") {
  118. const tbody = getParent(document.querySelector("form[action='pers_navlinks.php']"), "tbody");
  119. const tr = addElement("tr", tbody);
  120. const td = addElement("td", tr);
  121. const table = addElement("table", td);
  122. const quickLinkAmount = 10;
  123. let quickLinks = JSON.parse(GM_getValue(`QuickLinks${PlayerId}`, `[${Array(quickLinkAmount).fill('{"Name":"","Refernce":""}').join()}]`));
  124. if(quickLinks.length != quickLinkAmount) {
  125. GM_deleteValue(`QuickLinks${PlayerId}`);
  126. quickLinks = JSON.parse(`[${Array(quickLinkAmount).fill('{"Name":"","Refernce":""}').join()}]`);
  127. }
  128. //console.log(quickLinks)
  129. let i = 0;
  130. for(const quickLink of quickLinks) {
  131. const html = `
  132. <tr>
  133. <td>
  134. <input id="linkName${i}" name="linkName" type="text" style="width: 200px;" />
  135. <input id="linkValue${i}" name="linkValue" type="text" style="width: 300px;" />
  136. </td>
  137. </tr>`;
  138. table.insertAdjacentHTML('beforeend', html);
  139. table.querySelector(`#linkName${i}`).value = quickLink.Name;
  140. table.querySelector(`#linkValue${i}`).value = quickLink.Refernce;
  141. table.querySelector(`#linkName${i}`).addEventListener("change", saveQuickLinks);
  142. table.querySelector(`#linkValue${i}`).addEventListener("change", saveQuickLinks);
  143. i++;
  144. }
  145. }
  146. }
  147. function saveQuickLinks() {
  148. const quickLinks = Array.from(document.querySelectorAll("input[name=linkName]")).map(x => ({ Name: x.value, Refernce: document.getElementById(x.id.replace("linkName", "linkValue")).value }));
  149. //console.log(quickLinks)
  150. GM_setValue(`QuickLinks${PlayerId}`, JSON.stringify(quickLinks));
  151. }
  152. function addElement(type, parent, data, insertFirst = false) {
  153. let el = createElement(type, data);
  154. if(parent) {
  155. if(insertFirst) {
  156. parent.insertBefore(el, parent.firstChild);
  157. } else {
  158. parent.appendChild(el);
  159. }
  160. }
  161. return el;
  162. }
  163. function createElement(type, data) {
  164. let el = document.createElement(type);
  165. if(data) {
  166. for(let key in data) {
  167. if(key == "innerText" || key == "innerHTML") {
  168. el[key] = data[key];
  169. } else {
  170. el.setAttribute(key, data[key]);
  171. }
  172. }
  173. }
  174. return el;
  175. }
  176. function getParent(element, parentType, number = 1) {
  177. if(!element) {
  178. return;
  179. }
  180. let result = element;
  181. let foundNumber = 0;
  182. while(result = result.parentNode) {
  183. if(result.nodeName.toLowerCase() == parentType.toLowerCase()) {
  184. foundNumber++;
  185. if(foundNumber == number) {
  186. return result;
  187. }
  188. }
  189. }
  190. }
  191. function getUrlParamValue(url, paramName) { return (new URLSearchParams(url.split("?")[1])).get(paramName); }