HWM-UI-UX-MOD

try to take over the world!

当前为 2021-02-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name HWM-UI-UX-MOD
  3. // @namespace https://greasyfork.org/ru/scripts/421913-hwm-ui-ux-mod
  4. // @version 0.5
  5. // @description try to take over the world!
  6. // @author achepta
  7. // @include /^https{0,1}:\/\/((www|qrator)(\.heroeswm\.ru|\.lordswm\.com)|178\.248\.235\.15)\/.+/
  8. // @grant unsafeWindow
  9. // @grant GM_xmlhttpRequest
  10. // @grant GM_log
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14. (function (window, undefined) {
  15. let w;
  16. if (typeof unsafeWindow !== undefined) {
  17. w = unsafeWindow;
  18. } else {
  19. w = window;
  20. }
  21. if (w.self !== w.top) {
  22. return;
  23. }
  24. if (/cgame/.test(location.href)) {
  25. return
  26. }
  27. let allTexts = getAllTexts()
  28. let defaultSettings = getDefaultSettings()
  29.  
  30. let language = /lordswm/.test(location.href) ? "eng" : "rus"
  31. let settings = {}
  32. let headerInfo = {}
  33. let timersInfo = {}
  34.  
  35. loadSettings();
  36. loadTimersInfo();
  37.  
  38. if (settings['isDarkTheme'] && !/war\.php/.test(location.href)) {
  39. applyDarkTheme()
  40. }
  41. document.addEventListener("DOMContentLoaded", () => {
  42. if (!/war\.php/.test(location.href)) {
  43. processPage()
  44. addStyle();
  45. getHeaderInfo()
  46. drawNewHeader()
  47. processSettings();
  48. addMenu();
  49. } else {
  50. processBattle()
  51. }
  52. });
  53.  
  54.  
  55. function addStyle() {
  56. document.body.insertAdjacentHTML("beforeend", getStyles())
  57. }
  58.  
  59. function addMenu() {
  60. $('hwm_header_settings_button').addEventListener('click', handleOnSettingsButtonClick);
  61. }
  62.  
  63.  
  64. // logic
  65. function processSettings() {
  66. if (settings.isTimeWithSeconds) {
  67. showTimeWithSeconds()
  68. }
  69. if (settings.isShowTimers) {
  70. showTimers()
  71. }
  72. }
  73.  
  74. function getHeaderInfo() {
  75. headerInfo['logo'] = getHeaderLogo()
  76. headerInfo['mana_amount'] = getManaAmount()
  77. headerInfo['notifications'] = getHeaderNotifications()
  78. headerInfo['homeColor'] = getHomeButtonColor()
  79. headerInfo['battleColor'] = getBattleButtonColor()
  80. headerInfo['resources'] = getHeaderResources()
  81. headerInfo['online'] = getHwmOnline()
  82. }
  83.  
  84. function getHeaderLogo() {
  85. return document.querySelector("div.sh_logo > img").src
  86. }
  87.  
  88. function getManaAmount() {
  89. return $('mana_amount').textContent
  90. }
  91.  
  92. function getHeaderNotifications() {
  93. return Array.from(document.getElementsByClassName("NotificationIcon"))
  94. }
  95.  
  96. function getHomeButtonColor() {
  97. return document.querySelector("#MenuHome").offsetParent.classList.value.split("_").slice(-1)[0]
  98. }
  99.  
  100. function getBattleButtonColor() {
  101. return document.querySelector("#MenuBattles").offsetParent.classList.value.split("_").slice(-1)[0]
  102. }
  103.  
  104. function getHeaderResources() {
  105. let resources = {}
  106. let resourceDivs = document.querySelectorAll("div.sh_ResourcesItem")
  107. Array.from(resourceDivs).forEach(item => {
  108. let resName = getResNameFromImage(item.firstChild.src)
  109. resources[resName] = item.lastChild.textContent
  110. })
  111. return resources
  112. }
  113.  
  114. function getResNameFromImage(src) {
  115. return src.match(/(\w+)\.png/)[1]
  116. }
  117.  
  118. function getHwmOnline() {
  119. return document.querySelector("div.sh_extra.sh_extra_right > div.mm_extra_separator").nextElementSibling.textContent
  120. }
  121.  
  122. function drawNewHeader() {
  123. removeElement($('hwm_header'))
  124. document.body.insertAdjacentHTML('afterbegin', getNewHeaderTemplate())
  125. let heartData = document.body.textContent.match(/top_line_draw_canvas_heart\((\d{1,3}), (\d{1,3}), (\d{1,3})\);/)
  126. unsafeWindow.top_line_draw_canvas_heart(heartData[1], heartData[2], heartData[3])
  127. unsafeWindow.top_line_add_events_listeners()
  128. }
  129.  
  130. function showTimeWithSeconds() {
  131. let hwmDate = hwmDateToHuman(getHwmDate());
  132. let timePlace = $('hwm_time');
  133. timePlace.innerHTML = hwmDate
  134. setTimeout(showTimeWithSeconds, 1000)
  135. }
  136.  
  137. function showTimers() {
  138. $('timers_container').innerHTML = getTimersTemplate()
  139. setTimeout(showTimers, 1000)
  140. }
  141.  
  142. function applyDarkTheme() {
  143. document.head.insertAdjacentHTML("beforeend", getDarkStyles())
  144.  
  145. }
  146.  
  147. function showEmptyBackground() {
  148. document.body.insertAdjacentHTML('beforeend', getEmptyBackgroundTemplate());
  149. $('empty_background').addEventListener('click', handleOnBackgroundClick);
  150. }
  151.  
  152. function hideEmptyBackground() {
  153. removeElement($('empty_background'))
  154. }
  155.  
  156. function showSettings() {
  157. document.body.insertAdjacentHTML('beforeend', getSettingsTemplate())
  158. fillSettings()
  159. }
  160.  
  161. function fillSettings() {
  162. let settingsField = $('hwm_header_settings');
  163. for (const [key, value] of Object.entries(settings)) {
  164. settingsField.insertAdjacentHTML("beforeend",
  165. `<div id="${key}">
  166. <input id="${key}_checkbox" type="checkbox" ${value ? ' checked' : ''}>
  167. <label for="${key}_checkbox">${getTranslation(key)}</label>
  168. </div>
  169. `)
  170. $(`${key}`).addEventListener('click', () => {
  171. handleSettingsChange(key)
  172. })
  173. }
  174. }
  175.  
  176. function hideSettings() {
  177. removeElement($('hwm_header_settings'))
  178. }
  179.  
  180. function processButtonDropDown(buttonInfo) {
  181. if (buttonInfo.id === "MenuInventory" || buttonInfo.id === "MenuTavern") {
  182. return
  183. }
  184. let target = $(buttonInfo.id+"_expandable")
  185. if (buttonInfo.id === "MenuBattles") {
  186. Array.from(target.getElementsByTagName('a')).slice(8).forEach(item => {
  187. buttonInfo.dropDown.push([item.textContent, item.href, true])
  188. })
  189. }
  190. target.innerHTML = ''
  191. buttonInfo.dropDown.forEach(item => {
  192. if (item.length > 2) {
  193. target.insertAdjacentHTML('beforeend', `<a href="${item[1]}" style="text-decoration:none;"><div class="sh_dd_container_red">${item[0]}</div></a>`)
  194. } else {
  195. target.insertAdjacentHTML('beforeend', `<a href="${item[1]}" style="text-decoration:none;"><div>${getTranslation(item[0])}</div></a>`)
  196. }
  197. })
  198. target.insertAdjacentHTML("beforeend", `<img src="https://dcdn.heroeswm.ru/i/new_top/mm_dd_decorM.png" class="mm_decor2">`)
  199. target.insertAdjacentHTML("beforeend", `<img src="https://dcdn.heroeswm.ru/i/new_top/mm_dd_decorT.png" class="mm_decor3">`)
  200. }
  201.  
  202. function processPage() {
  203. if (/home/.test(location.href)) {
  204. let isPremium = document.body.innerHTML.match(/star.gif/)
  205. timersInfo.isPremium = !!isPremium
  206. }
  207. if (/object_do/.test(location.href)) {
  208. if (document.body.textContent.match(/(successfully|устроены)/)) {
  209. timersInfo.labor_guild_timer_data = getHwmDate()
  210. }
  211. }
  212. let battleId = new URLSearchParams(new URL(document.referrer).search).get("warid")
  213. if (timersInfo.leader_guild_timer_data && !timersInfo.leader_guild_timer_data.timeSet && battleId === timersInfo.leader_guild_timer_data.battleId) {
  214. timersInfo.leader_guild_timer_data.timeSet = getHwmDate()
  215. } else if (timersInfo.thief_guild_timer_data && !timersInfo.thief_guild_timer_data.timeSet && battleId === timersInfo.thief_guild_timer_data.battleId) {
  216. timersInfo.thief_guild_timer_data.timeSet = getHwmDate()
  217. } else if (timersInfo.hunt_guild_timer_data && !timersInfo.hunt_guild_timer_data.timeSet && battleId === timersInfo.hunt_guild_timer_data.battleId) {
  218. timersInfo.hunt_guild_timer_data.timeSet = getHwmDate()
  219. }
  220. set("timers_data", timersInfo)
  221. }
  222.  
  223. function processBattle() {
  224. let battleData = unsafeWindow.run_all.toString()
  225. let battleType = battleData.match(/btype\|(\d{1,10})/)[1]
  226. let battlePlayer = battleData.match(/plid1\|(\d{1,10})/)[1]
  227. let battleId = new URLSearchParams(window.location.search).get("warid")
  228. if (battlePlayer === getCookie("pl_id")) {
  229. if (battleType === "127") {
  230. if ("leader_guild_timer_data" in timersInfo) {
  231. if (timersInfo.leader_guild_timer_data.battleId < battleId) {
  232. timersInfo.leader_guild_timer_data = {"battleId": battleId}
  233. }
  234. } else {
  235. timersInfo.leader_guild_timer_data = {"battleId": battleId}
  236. }
  237. } else if (battleType === "66") {
  238. if ("thief_guild_timer_data" in timersInfo) {
  239. if (timersInfo.thief_guild_timer_data.battleId < battleId) {
  240. timersInfo.thief_guild_timer_data = {"battleId": battleId}
  241. }
  242. } else {
  243. timersInfo.thief_guild_timer_data = {"battleId": battleId}
  244. }
  245. } else if (battleType === "0") {
  246. if ("hunt_guild_timer_data" in timersInfo) {
  247. if (timersInfo.hunt_guild_timer_data.battleId < battleId) {
  248. timersInfo.hunt_guild_timer_data = {"battleId": battleId}
  249. }
  250. } else {
  251. timersInfo.hunt_guild_timer_data = {"battleId": battleId}
  252. }
  253. }
  254. set("timers_data", timersInfo)
  255. }
  256. }
  257.  
  258. // listeners
  259. function handleOnSettingsButtonClick() {
  260. showEmptyBackground();
  261. showSettings();
  262. }
  263.  
  264. function handleOnBackgroundClick() {
  265. hideEmptyBackground();
  266. hideSettings();
  267. }
  268.  
  269. function handleSettingsChange(key) {
  270. settings[key] = $(`${key}_checkbox`).checked
  271. set('hwm_header_settings', settings)
  272. }
  273.  
  274. // templates
  275. function getSettingsButtonTemplate() {
  276. return `
  277. <img
  278. id="hwm_header_settings_button"
  279. src="https://dcdn3.heroeswm.ru/i/combat/btn_settings.png?v=8"
  280. height="18"
  281. alt="Header settings"
  282. style="position: relative; filter: drop-shadow(0.01rem 0.01rem 0 black) drop-shadow(-0.01rem -0.01rem 0 black); transform: rotate(22.5deg)"
  283. title="Header settings"
  284. >`
  285. }
  286.  
  287. function getEmptyBackgroundTemplate() {
  288. return `
  289. <div id="empty_background" style="
  290. position: absolute;
  291. left: 0;
  292. top: 0;
  293. width: 100%;
  294. height: ${getScrollHeight()};
  295. background: #000000;
  296. opacity: 0.5;
  297. z-index: 1100;
  298. "></div>
  299. `
  300. }
  301.  
  302. function getSettingsTemplate() {
  303. return `
  304. <div id="hwm_header_settings" style="
  305. position: absolute;
  306. left: ${(getClientWidth() - 600) / 2}px;
  307. top: ${window.pageYOffset + 155}px;
  308. width: 600px;
  309. background: #F6F3EA;
  310. z-index: 1101;
  311. ">
  312. </div>
  313. `
  314. }
  315.  
  316. function getNewHeaderTemplate() {
  317. return `
  318. <div id="new_header">
  319. <div class="top_line">
  320. <div class="top_left_container">
  321. <!-- <div class="top_left_left">-->
  322. <!-- </div>-->
  323. <div class="top_wing_middle">
  324. <div id="notifications">
  325. ${getNotificationsTemplate()}
  326. </div>
  327. </div>
  328. <div class="top_left_right">
  329. <div id="heart_container">
  330. <div class="sh_HMResIconBlock">
  331. <canvas width="64px" height="64px" id="heart"></canvas>
  332. </div>
  333. <div style="display: none;" id="health_amount">100</div>
  334. </div>
  335. </div>
  336. </div>
  337. <div class="top_resource_container" id="top_resource_container">
  338. <div id="ResourcesPanel" class="sh_ResourcesPanel">
  339. ${getResourcesTemplate()}
  340. </div>
  341. </div>
  342. <div class="top_right_container">
  343. <div class="top_right_left">
  344. <div id="mana_container">
  345. <div class="sh_HMResIconBlock mana"></div>
  346. <div class="mana_animation"></div>
  347. <div style="display: none" id="mana_amount">${headerInfo.mana_amount}</div>
  348. </div>
  349. </div>
  350. <div class="top_wing_middle">
  351. <div class="time_online_radio_container">
  352. <div id="hwm_time"></div>
  353. <div class="mm_extra_separator"></div>
  354. <div id="hwm_online">${headerInfo['online']} online</div>
  355. <div class="mm_extra_separator"></div>
  356. <div class="mm_extra_radio" onclick="hwm_top_line_open_radio(620, 400);return false;"></div>
  357. <div class="mm_extra_separator"></div>
  358. <div id="">${getSettingsButtonTemplate()}</div>
  359. </div>
  360. </div>
  361. <!-- <div class="top_right_right">-->
  362.  
  363. <!-- </div>-->
  364. </div>
  365. </div>
  366. <div class="new_header_menu">
  367. <!-- <img src="https://dcdn.heroeswm.ru/i/new_top/mm_decor1.png" class="mm_decor1">-->
  368. <div class="left_dragon">
  369. <img height="70px" src="https://i.pinimg.com/originals/6c/2e/0b/6c2e0be6ebdad0e7f4bc86bc1f10e451.png">
  370. </div>
  371. <div class="middle_menus">
  372. <div class="timers_container" id="timers_container"></div>
  373. <div class="common_menu_container">
  374. ${getMenuButtonsTemplate()}
  375. </div>
  376. </div>
  377. <div class="right_dragon">
  378. <img height="70px" src="https://i.imgur.com/oqyVp7G.png">
  379. </div>
  380. </div>
  381. </div>
  382. `
  383. }
  384.  
  385. function getNotificationsTemplate() {
  386. return headerInfo['notifications'].reduce((result, current) => {
  387. // #говнокод
  388. if (current.src.includes("pismo")) {
  389. return result + `<a href="sms.php">${current.outerHTML.toString()}</a>`;
  390. } else {
  391. return result + current.outerHTML.toString()
  392. }}, "")
  393. }
  394.  
  395. function getResourcesTemplate() {
  396. let newResources = []
  397. let resourceLinks = getResourceLinks()
  398. for (const [key, value] of Object.entries(headerInfo['resources'])) {
  399. let template = `
  400. <div class="sh_ResourcesItem">
  401. <a href="${resourceLinks[key]}">
  402. <img class="sh_ResourcesItem_icon" src="https://dcdn.heroeswm.ru/i/r/48/${key}.png?v=3.23de65" alt="${key}" title="${key}">
  403. </a>
  404. <span class="select_auto_enabled">${value}</span></div>
  405. `
  406. newResources.push(template)
  407. }
  408. return newResources.join(`<div class="mm_rp_separator"></div>`)
  409. }
  410.  
  411. function getMenuButtonsTemplate() {
  412. let buttonsToShow = getAvailableButtons()
  413. return buttonsToShow.reduce((result, current) => result + getMenuButtonHTML(current), "")
  414. }
  415.  
  416. function getAvailableButtons() {
  417. let buttons = []
  418. for (const [key, value] of Object.entries(getButtonInfos())) {
  419. if (settings[key]) {
  420. buttons.push(value)
  421. }
  422. }
  423. return buttons
  424. }
  425.  
  426. function getMenuButtonHTML(buttonInfo) {
  427. processButtonDropDown(buttonInfo)
  428. let buttonInside = ``
  429. if (settings['isTextButtons']) {
  430. buttonInside = `<div class="menu_button_text">${getTranslation(buttonInfo.id)}</div>`
  431. } else {
  432. buttonInside = `<img class="mm_item_icon" src="${buttonInfo.image}">`
  433. }
  434. let buttonColor = ``
  435. if (headerInfo['homeColor'] === 'red') {
  436. buttonColor = 'red'
  437. } else if (headerInfo['battleColor'] === 'orange' && buttonInfo.id === "MenuBattles") {
  438. buttonColor = 'orange'
  439. } else if (headerInfo['battleColor'] === 'red' && buttonInfo.id === "MenuBattles") {
  440. buttonColor = 'red'
  441. } else {
  442. buttonColor = 'blue'
  443. }
  444. return `
  445. <div class="mm_item mm_item_${buttonColor}">
  446. <a href="${buttonInfo.href}">
  447. <div class="mm_item_inside" id="${buttonInfo.id}" hwm_label="">
  448. ${buttonInside}
  449. </div>
  450. </a>
  451. </div>
  452. `
  453. }
  454.  
  455. function getTimersTemplate() {
  456. let isPremium = timersInfo.isPremium ? timersInfo.isPremium : false
  457. let result = ''
  458. if (timersInfo.labor_guild_timer_data) {
  459. let timeCount = isPremium ? 60 : 60
  460. result += `
  461. <div class="mm_item mm_item_blue">
  462. <div class="menu_button_text">${getTranslation("labor_guild")} ${getRemainingTime(timersInfo.labor_guild_timer_data, timeCount)}</div>
  463. </div>`
  464. } else {
  465. result += `
  466. <div class="mm_item mm_item_blue">
  467. <div class="menu_button_text">${getTranslation("labor_guild")} 00:00</div>
  468. </div>`
  469. }
  470. if (timersInfo.hunt_guild_timer_data && timersInfo.hunt_guild_timer_data.timeSet) {
  471. let timeCount = isPremium ? 28 : 40
  472. result += `
  473. <div class="mm_item mm_item_blue">
  474. <div class="menu_button_text">${getTranslation("hunt_guild")} ${getRemainingTime(timersInfo.hunt_guild_timer_data.timeSet, timeCount)}</div>
  475. </div>`
  476. } else {
  477. result += `
  478. <div class="mm_item mm_item_blue">
  479. <div class="menu_button_text">${getTranslation("hunt_guild")} 00:00</div>
  480. </div>`
  481. }
  482. if (timersInfo.thief_guild_timer_data && timersInfo.thief_guild_timer_data.timeSet) {
  483. let timeCount = isPremium ? 42 : 60
  484. result += `
  485. <div class="mm_item mm_item_blue">
  486. <div class="menu_button_text">${getTranslation("thief_guild")} ${getRemainingTime(timersInfo.thief_guild_timer_data.timeSet, timeCount)}</div>
  487. </div>`
  488. } else {
  489. result += `
  490. <div class="mm_item mm_item_blue">
  491. <div class="menu_button_text">${getTranslation("thief_guild")} 00:00</div>
  492. </div>`
  493. }
  494. if (timersInfo.leader_guild_timer_data && timersInfo.leader_guild_timer_data.timeSet) {
  495. let timeCount = isPremium ? 180 : 180
  496. result += `
  497. <div class="mm_item mm_item_blue">
  498. <div class="menu_button_text">${getTranslation("leader_guild")} ${getRemainingTime(timersInfo.leader_guild_timer_data.timeSet, timeCount)}</div>
  499. </div>`
  500. } else {
  501. result += `
  502. <div class="mm_item mm_item_blue">
  503. <div class="menu_button_text">${getTranslation("leader_guild")} 00:00</div>
  504. </div>`
  505. }
  506. return result
  507. }
  508. function getRemainingTime(timeSet, timeCount) {
  509. let hwmDate = getHwmDate()
  510. let timeSetHwm = new Date(timeSet)
  511. return secondsToHumanDate(diffDateInSeconds(timeSetHwm, hwmDate) + timeCount * 60)
  512. }
  513. function diffDateInSeconds(dt1, dt2) {
  514. return Math.round((dt1.getTime() - dt2.getTime()) / 1000);
  515. }
  516. // helpers
  517. function getCookie(name) {
  518. const value = `; ${document.cookie}`;
  519. const parts = value.split(`; ${name}=`);
  520. if (parts.length === 2) return parts.pop().split(';').shift();
  521. }
  522.  
  523. function doGet(url, callback) {
  524. GM_xmlhttpRequest({
  525. method: "GET",
  526. url: url,
  527. overrideMimeType: "text/xml; charset=windows-1251",
  528. onload: function (res) {
  529. callback(new DOMParser().parseFromString(res.responseText, "text/html"))
  530. }
  531. });
  532. }
  533.  
  534. function doPost(url, params, callback) {
  535. GM_xmlhttpRequest({
  536. method: "POST",
  537. url: url,
  538. data: params,
  539. onload: callback,
  540. });
  541. }
  542.  
  543. function removeElement(element) {
  544. element.parentNode.removeChild(element)
  545. }
  546.  
  547. function $(id, where = document) {
  548. return where.querySelector(`#${id}`);
  549. }
  550.  
  551. function get(key, def) {
  552. let result = JSON.parse(localStorage[key] === undefined ? null : localStorage[key]);
  553. return result == null ? def : result;
  554.  
  555. }
  556.  
  557. function set(key, val) {
  558. localStorage[key] = JSON.stringify(val);
  559. }
  560.  
  561. function getScrollHeight() {
  562. return Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
  563. }
  564.  
  565. function getClientWidth() {
  566. return document.compatMode === 'CSS1Compat' && document.documentElement ? document.documentElement.clientWidth : document.body.clientWidth;
  567. }
  568.  
  569. function findAll(regexPattern, sourceString) {
  570. let output = []
  571. let match
  572. let regexPatternWithGlobal = RegExp(regexPattern, [...new Set("g" + regexPattern.flags)].join(""))
  573. while (match = regexPatternWithGlobal.exec(sourceString)) {
  574. delete match.input
  575. output.push(match)
  576. }
  577. return output
  578. }
  579.  
  580. function sortByKey(array, key) {
  581. return array.sort((a, b) => {
  582. let x = a[key];
  583. let y = b[key];
  584. return ((x < y) ? -1 : ((x > y) ? 1 : 0));
  585. });
  586. }
  587.  
  588. function getHwmDate() {
  589. let today = new Date();
  590. let localOffset = -(today.getTimezoneOffset() / 60);
  591. let destinationOffset = +3;
  592.  
  593. let offset = destinationOffset - localOffset;
  594. return new Date(new Date().getTime() + offset * 3600 * 1000)
  595.  
  596. }
  597.  
  598. function hwmDateToHuman(hwmDate) {
  599. let hours = hwmDate.getHours().toString().length === 1
  600. ? "0" + hwmDate.getHours().toString()
  601. : hwmDate.getHours().toString()
  602. let minutes = hwmDate.getMinutes().toString().length === 1
  603. ? "0" + hwmDate.getMinutes().toString()
  604. : hwmDate.getMinutes().toString()
  605. let seconds = hwmDate.getSeconds().toString().length === 1
  606. ? "0" + hwmDate.getSeconds().toString()
  607. : hwmDate.getSeconds().toString()
  608. return hours + ":" + minutes + ":" + seconds
  609. }
  610.  
  611. function secondsToHumanDate(seconds) {
  612. if (seconds < 0) {
  613. return "00:00"
  614. }
  615. // Hours, minutes and seconds
  616. var hrs = ~~(seconds / 3600);
  617. var mins = ~~((seconds % 3600) / 60);
  618. var secs = ~~seconds % 60;
  619.  
  620. // Output like "1:01" or "4:03:59" or "123:03:59"
  621. var ret = "";
  622. if (hrs > 0) {
  623. ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
  624. }
  625. ret += "" + mins + ":" + (secs < 10 ? "0" : "");
  626. ret += "" + secs;
  627. return ret;
  628. }
  629.  
  630. function getTranslation(textId) {
  631. return allTexts[textId][language]
  632. }
  633.  
  634. function loadSettings() {
  635. settings = get('hwm_header_settings', defaultSettings)
  636. for (const [key, value] of Object.entries(defaultSettings)) {
  637. if (settings[key] === undefined) {
  638. settings[key] = value
  639. }
  640. }
  641. }
  642.  
  643. function loadTimersInfo() {
  644. timersInfo = get('timers_data', {})
  645. }
  646. function getAllTexts() {
  647. return {
  648. 'isTimeWithSeconds': {
  649. "rus": "Показывать время с секундами",
  650. "eng": "Show time with seconds",
  651. },
  652. 'isShowTimers': {
  653. "rus": "Показывать таймеры гильдий",
  654. "eng": "Show guilds' timers",
  655. },
  656. 'isDarkTheme': {
  657. "rus": "Темная тема",
  658. "eng": "Dark theme"
  659. },
  660. 'isTextButtons': {
  661. "rus": "Старые текстовые кнопки",
  662. "eng": "Show old text buttons"
  663. },
  664. 'isHomeButton': {
  665. "rus": "Персонаж",
  666. "eng": "Home"
  667. },
  668. 'isInventoryButton': {
  669. "rus": "Инвентарь",
  670. "eng": "Inventory"
  671. },
  672. 'isMapButton': {
  673. "rus": "Карта",
  674. "eng": "Map"
  675. },
  676. 'isBattleButton': {
  677. "rus": "Битвы",
  678. "eng": "Battles"
  679. },
  680. 'isTavernButton': {
  681. "rus": "Таверна",
  682. "eng": "Tavern"
  683. },
  684. 'isRouletteButton': {
  685. "rus": "Рулетка",
  686. "eng": "Roulette"
  687. },
  688. 'isLeaderboardButton': {
  689. "rus": "Рейтинг",
  690. "eng": "Leaderboards"
  691. },
  692. 'isForumButton': {
  693. "rus": "Форум",
  694. "eng": "Forum"
  695. },
  696. 'isChatButton': {
  697. "rus": "Чат",
  698. "eng": "Chat"
  699. },
  700. 'MenuHome': {
  701. "rus": "Персонаж",
  702. "eng": "Home"
  703. },
  704. 'MenuInventory': {
  705. "rus": "Инвентарь",
  706. "eng": "Inventory"
  707. },
  708. 'MenuMap': {
  709. "rus": "Карта",
  710. "eng": "Map"
  711. },
  712. 'MenuBattles': {
  713. "rus": "Битвы",
  714. "eng": "Battles"
  715. },
  716. 'MenuTavern': {
  717. "rus": "Таверна",
  718. "eng": "Tavern"
  719. },
  720. 'MenuRoulette': {
  721. "rus": "Рулетка",
  722. "eng": "Roulette"
  723. },
  724. 'MenuStat': {
  725. "rus": "Рейтинг",
  726. "eng": "Leaderboards"
  727. },
  728. 'MenuForum': {
  729. "rus": "Форум",
  730. "eng": "Forum"
  731. },
  732. 'MenuChat': {
  733. "rus": "Чат",
  734. "eng": "Chat"
  735. },
  736. 'myself': {
  737. "rus": "Я",
  738. "eng": "Myself"
  739. },
  740. 'inventory': {
  741. "rus": "Инвентарь",
  742. "eng": "Inventory"
  743. },
  744. 'shop': {
  745. "rus": "Магазин",
  746. "eng": "Artifact shop"
  747. },
  748. 'auction': {
  749. "rus": "Рынок",
  750. "eng": "Market"
  751. },
  752. 'choose_army': {
  753. "rus": "Набор армии",
  754. "eng": "Recruiting"
  755. },
  756. 'castle': {
  757. "rus": "Замок",
  758. "eng": "Castle"
  759. },
  760. 'skills': {
  761. "rus": "Навыки",
  762. "eng": "Talents"
  763. },
  764. 'mailbox': {
  765. "rus": "Почта",
  766. "eng": "Mailbox"
  767. },
  768. 'transfer': {
  769. "rus": "Передача ресурсов",
  770. "eng": "Transfer"
  771. },
  772. 'facility1': {
  773. "rus": "Добыча",
  774. "eng": "Mining"
  775. },
  776. 'facility2': {
  777. "rus": "Обработка",
  778. "eng": "Machining"
  779. },
  780. 'facility3': {
  781. "rus": "Производство",
  782. "eng": "Production"
  783. },
  784. 'houses': {
  785. "rus": "Дома",
  786. "eng": "Public services"
  787. },
  788. 'one_to_one': {
  789. "rus": "Дуэли",
  790. "eng": "Duels"
  791. },
  792. 'many_to_many': {
  793. "rus": "Групповые бои",
  794. "eng": "Group battles"
  795. },
  796. 'guild_pvp': {
  797. "rus": "Гильдия тактиков",
  798. "eng": "Commanders' guild"
  799. },
  800. 'guild_task': {
  801. "rus": "Гильдия стражей",
  802. "eng": "Watchers' guild"
  803. },
  804. 'guild_leader': {
  805. "rus": "Гильдия лидеров",
  806. "eng": "Leaders guild"
  807. },
  808. 'clanwars': {
  809. "rus": "Бои за территории",
  810. "eng": "Clan wars"
  811. },
  812. 'tournaments': {
  813. "rus": "Турниры",
  814. "eng": "Tounaments"
  815. },
  816. 'spin_history': {
  817. "rus": "История игр",
  818. "eng": "Spin history"
  819. },
  820. 'lucky_boxes': {
  821. "rus": "Редкие ларцы",
  822. "eng": "Chests of abundance"
  823. },
  824. 'top_heroes': {
  825. "rus": "Рейтинг воинов",
  826. "eng": "Top warriors"
  827. },
  828. 'top_clans': {
  829. "rus": "Рейтинг кланов",
  830. "eng": "Top clans"
  831. },
  832. 'top_hunters': {
  833. "rus": "Рейтинг охотников",
  834. "eng": "Top hunters"
  835. },
  836. 'top_mercenaries': {
  837. "rus": "Рейтинг наемников",
  838. "eng": "Top mercenaries"
  839. },
  840. 'top_shareholders': {
  841. "rus": "Рейтинг акционеров",
  842. "eng": "Top shareholders"
  843. },
  844. 'personal_records': {
  845. "rus": "Мои охоты",
  846. "eng": "My hunt records"
  847. },
  848. 'general_forum': {
  849. "rus": "Общий форум",
  850. "eng": "General forum"
  851. },
  852. 'help_forum': {
  853. "rus": "Помощь по игре",
  854. "eng": "Q&A forum"
  855. },
  856. 'trade_forum': {
  857. "rus": "Торговый форум",
  858. "eng": "Trade forums"
  859. },
  860. 'reference': {
  861. "rus": "Об игре",
  862. "eng": "About the game"
  863. },
  864. 'hwm_newspaper': {
  865. "rus": "Новостная лента",
  866. "eng": "Daily news"
  867. },
  868. 'chat_1': {
  869. "rus": "Комната вопросов",
  870. "eng": "Inquiry"
  871. },
  872. 'chat_2': {
  873. "rus": "Общая комната",
  874. "eng": "Common"
  875. },
  876. 'chat_3': {
  877. "rus": "Торговая палата",
  878. "eng": "Merchant"
  879. },
  880. 'chat_4': {
  881. "rus": "Рулетка",
  882. "eng": "Roulette"
  883. },
  884. 'chat_5': {
  885. "rus": "Карты",
  886. "eng": "Tavern"
  887. },
  888. 'labor_guild': {
  889. "rus": "ГР",
  890. "eng": "LG"
  891. },
  892. 'leader_guild': {
  893. "rus": "ГЛ",
  894. "eng": "LeG"
  895. },
  896. 'hunt_guild': {
  897. "rus": "ГО",
  898. "eng": "HG"
  899. },
  900. 'thief_guild': {
  901. "rus": "ГВ",
  902. "eng": "TG"
  903. },
  904. '': {
  905. "rus": "",
  906. "eng": ""
  907. },
  908.  
  909. }
  910. }
  911.  
  912. function getDefaultSettings() {
  913. return {
  914. "isTimeWithSeconds": true,
  915. "isShowTimers": true,
  916. "isDarkTheme": false,
  917. "isTextButtons": false,
  918. "isHomeButton": true,
  919. "isInventoryButton": false,
  920. "isMapButton": true,
  921. "isBattleButton": true,
  922. "isTavernButton": true,
  923. "isRouletteButton": true,
  924. "isLeaderboardButton": true,
  925. "isForumButton": true,
  926. "isChatButton": true,
  927. }
  928. }
  929.  
  930. function getButtonInfos() {
  931. return {
  932. "isHomeButton": {
  933. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelCharacter.png",
  934. "id": "MenuHome",
  935. "href": "home.php",
  936. "dropDown": [
  937. ["myself", `pl_info.php?id=${getCookie("pl_id")}`],
  938. ["inventory", "inventory.php"],
  939. ["shop", "shop.php"],
  940. ["auction", "auction.php"],
  941. ["choose_army", "army.php"],
  942. ["castle", "castle.php"],
  943. ["skills", "skillwheel.php"],
  944. ["mailbox", "sms.php"],
  945. ["transfer", "transfer.php"],
  946. ]
  947. },
  948. "isInventoryButton": {
  949. "image": "https://dcdn.heroeswm.ru/i/mobile_view/icons/_panelInventory.png",
  950. "id": "MenuInventory",
  951. "href": "inventory.php",
  952. "dropDown": []
  953. },
  954. "isMapButton": {
  955. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelMap.png",
  956. "id": "MenuMap",
  957. "href": "map.php",
  958. "dropDown": [
  959. ["facility1", "map.php?st=mn"],
  960. ["facility2", "map.php?st=fc"],
  961. ["facility3", "map.php?st=sh"],
  962. ["houses", "map.php?st=hs"],
  963. ]
  964. },
  965. "isBattleButton": {
  966. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelBattles.png",
  967. "id": "MenuBattles",
  968. "href": "bselect.php",
  969. "dropDown": [
  970. ["one_to_one", "one_to_one.php"],
  971. ["many_to_many", "group_wars.php"],
  972. ["guild_pvp", "pvp_guild.php"],
  973. ["guild_task", "task_guild.php"],
  974. ["guild_leader", "leader_guild.php"],
  975. ["clanwars", "mapwars.php"],
  976. ["tournaments", "tournaments.php"],
  977. ]
  978. },
  979. "isTavernButton": {
  980. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelTavern.png",
  981. "id": "MenuTavern",
  982. "href": "tavern.php",
  983. "dropDown": []
  984. },
  985. "isRouletteButton": {
  986. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelRoulette.png",
  987. "id": "MenuRoulette",
  988. "href": "roulette.php",
  989. "dropDown": [
  990. ["spin_history", "allroul.php"],
  991. ["lucky_boxes", "gift_box_log.php"],
  992.  
  993. ]
  994. },
  995. "isLeaderboardButton": {
  996. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelRate.png",
  997. "id": "MenuStat",
  998. "href": "plstats.php",
  999. "dropDown": [
  1000. ["top_heroes", "plstats.php"],
  1001. ["top_clans", "clanstat.php"],
  1002. ["top_hunters", "plstats_hunters.php"],
  1003. ["top_mercenaries", "plstats_merc.php"],
  1004. ["top_shareholders", "sholders_stat.php"],
  1005. ["personal_records", `pl_hunter_stat.php?id=${getCookie("pl_id")}`],
  1006.  
  1007. ]
  1008. },
  1009. "isForumButton": {
  1010. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelForum.png",
  1011. "id": "MenuForum",
  1012. "href": "forum.php",
  1013. "dropDown": [
  1014. ["general_forum", "forum_thread.php?id=2"],
  1015. ["help_forum", "forum_thread.php?id=10"],
  1016. ["trade_forum", "forum.php#t1"],
  1017. ["reference", "help.php"],
  1018. ["hwm_newspaper", "https://daily.heroeswm.ru/"],
  1019.  
  1020. ]
  1021. },
  1022. "isChatButton": {
  1023. "image": "https://dcdn.heroeswm.ru/i/new_top/_panelChat.png",
  1024. "id": "MenuChat",
  1025. "href": "frames.php",
  1026. "dropDown": [
  1027. ["chat_1", "frames.php?room=0"],
  1028. ["chat_2", "frames.php?room=1"],
  1029. ["chat_3", "frames.php?room=2"],
  1030. ["chat_4", "frames.php?room=3"],
  1031. ["chat_5", "frames.php?room=4"],
  1032. ]
  1033. },
  1034. }
  1035. }
  1036.  
  1037. function getResourceLinks() {
  1038. return {
  1039. "gold": "roulette.php",
  1040. "wood": "auction.php?cat=res&sort=0&type=1",
  1041. "ore": "auction.php?cat=res&sort=0&type=2",
  1042. "mercury": "auction.php?cat=res&sort=0&type=3",
  1043. "sulfur": "auction.php?cat=res&sort=0&type=4",
  1044. "crystals": "auction.php?cat=res&sort=0&type=5",
  1045. "gems": "auction.php?cat=res&sort=0&type=6",
  1046. "diamonds": "hwm_donate_page_new.php",
  1047. }
  1048. }
  1049.  
  1050. function getStyles() {
  1051. return `
  1052. <style>
  1053. ${settings.isTextButtons ? ".mm_item, .mm_item_inside {height:24px}; .mm_item_inside {display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;} .menu_button_text{height:100%}" : ""};
  1054. body {
  1055. margin: 0;
  1056. padding: 0;
  1057. }
  1058.  
  1059. #new_header {
  1060. display: flex;
  1061. flex-direction: column;
  1062. align-items: center;
  1063. }
  1064.  
  1065. .top_line {
  1066. width: 100%;
  1067. height: 32px;
  1068. display: flex;
  1069. flex-direction: row;
  1070. flex-wrap: nowrap;
  1071. }
  1072.  
  1073. .top_left_container, .top_right_container {
  1074. height: 100%;
  1075. display: flex;
  1076. flex-direction: row;
  1077. flex-wrap: nowrap;
  1078. flex-grow: 1;
  1079. }
  1080.  
  1081. .top_left_left {
  1082. height: 100%;
  1083. width: 52px;
  1084. background-image: url("https://dcdn.heroeswm.ru/i/new_top/extra_bg_side2.png");
  1085. background-size: 256px 32px;
  1086. background-repeat: no-repeat;
  1087. }
  1088.  
  1089. .top_left_right {
  1090. min-width: 100px;
  1091. background: url("https://dcdn.heroeswm.ru/i/new_top/extra_bg_side1.png") no-repeat top right;
  1092. background-size: 256px 32px;
  1093.  
  1094. }
  1095.  
  1096. /*#logo_container {*/
  1097. /* position: relative;*/
  1098. /*}*/
  1099. /*.logo {*/
  1100. /* max-width: 128px;*/
  1101. /* max-height: 64px;*/
  1102. /*}*/
  1103. #notifications {
  1104. height: 32px;
  1105. float: right;
  1106. display: flex;
  1107. flex-direction: row;
  1108. flex-wrap: nowrap;
  1109. align-items: center;
  1110. margin-right: 10%;
  1111. }
  1112.  
  1113. #heart_container {
  1114. background-image: url("https://dcdn.heroeswm.ru/i/new_top/mm_rp_health.png");
  1115. background-size: contain;
  1116. width: 32px;
  1117. height: 32px;
  1118. margin: auto;
  1119. }
  1120.  
  1121. #heart_container:hover #health_amount {
  1122. display: initial !important;
  1123. position: absolute;
  1124. color: white;
  1125. transform: translate(10%, -100%);
  1126. text-shadow: 1px 0 0 #000, 0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000;
  1127.  
  1128. }
  1129.  
  1130. .sh_HMResIconBlock {
  1131. position: relative;
  1132. left: 15px;
  1133. top: 15px;
  1134. }
  1135.  
  1136. .health_animation {
  1137. position: relative;
  1138. }
  1139.  
  1140. #heart {
  1141. width: 27px;
  1142. height: 27px;
  1143. }
  1144.  
  1145. #mana_container {
  1146. background-image: url("https://dcdn.heroeswm.ru/i/new_top/mm_rp_mana.png");
  1147. background-size: contain;
  1148. width: 32px;
  1149. height: 32px;
  1150. margin: auto;
  1151. display: grid;
  1152. grid-template-columns: 1fr;
  1153. grid-template-rows: 1fr;
  1154. overflow: hidden;
  1155. }
  1156. .mana_animation {
  1157. position: relative;
  1158. grid-column-start: 1;
  1159. grid-row-start: 1;
  1160. z-index: 4;
  1161. }
  1162.  
  1163. .mana {
  1164. grid-column-start: 1;
  1165. grid-row-start: 1;
  1166. z-index: 3;
  1167. }
  1168.  
  1169. #mana_amount {
  1170. grid-column-start: 1;
  1171. grid-row-start: 1;
  1172. z-index: 5;
  1173. margin: auto;
  1174. color: white;
  1175. }
  1176.  
  1177. #mana_container:hover #mana_amount {
  1178. display: initial !important;
  1179. color: white;
  1180. text-shadow: 1px 0 0 #000, 0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000;
  1181. }
  1182.  
  1183. .top_right_right {
  1184. width: 52px;
  1185. background: url("https://dcdn.heroeswm.ru/i/new_top/extra_bg_side2.png") no-repeat top right;
  1186. background-size: 256px 32px;
  1187. }
  1188.  
  1189. .top_right_left {
  1190. min-width: 100px;
  1191. background: url("https://dcdn.heroeswm.ru/i/new_top/extra_bg_side1.png") no-repeat top left;
  1192. background-size: 256px 32px;
  1193. }
  1194.  
  1195. .top_wing_middle {
  1196. min-width: 175px;
  1197. width: 100%;
  1198. background: url("https://dcdn.heroeswm.ru/i/new_top/extra_bg_mid.png") repeat-x top left;
  1199. background-size: 32px;
  1200. }
  1201.  
  1202. .time_online_radio_container {
  1203. display: flex;
  1204. flex-direction: row;
  1205. flex-wrap: nowrap;
  1206. align-items: center;
  1207. margin-left: 10%;
  1208. }
  1209. #hwm_time, #hwm_online {
  1210. color: #b12424;
  1211. }
  1212.  
  1213. .top_resource_container {
  1214. background: url("https://dcdn.heroeswm.ru/i/new_top/rp_bg_mid.png");
  1215. background-size: contain;
  1216. }
  1217.  
  1218. .new_header_menu {
  1219. background: url("https://dcdn.heroeswm.ru/i/new_top/mm_dd_tile.jpg");
  1220. min-height: 70px;
  1221. padding: 0;
  1222. width: 100%;
  1223. display: flex;
  1224. flex-direction: row;
  1225. flex-wrap: nowrap;
  1226. justify-content: space-between;
  1227. }
  1228. .common_menu_container {
  1229. margin-top: 5px;
  1230. display: flex;
  1231. flex-direction: row;
  1232. flex-wrap: nowrap;
  1233. justify-content: center;
  1234. align-items: center;
  1235. overflow: hidden;
  1236. }
  1237. .timers_container {
  1238. display: flex;
  1239. flex-direction: row;
  1240. flex-wrap: nowrap;
  1241. justify-content: center;
  1242. align-items: center;
  1243. overflow: hidden;
  1244. }
  1245. .mm_item {
  1246. margin: 0;
  1247. }
  1248. .mm_item + .mm_item {
  1249. margin-left: 5px;
  1250. }
  1251.  
  1252. .left_dragon, .right_dragon {
  1253. }
  1254. .left_dragon {
  1255. transform: scaleX(-1);
  1256. }
  1257. .middle_menus {
  1258. display: flex;
  1259. flex-direction: column;
  1260. justify-content: center;
  1261. }
  1262. .menu_button_text {
  1263. display: flex;
  1264. justify-content: center;
  1265. align-items: center;
  1266. color: #fad49f;
  1267. font-weight: bold;
  1268. }
  1269. </style>
  1270. `
  1271. }
  1272.  
  1273. function getDarkStyles() {
  1274. let mainTextColor = `#d0d0d0`
  1275. return `
  1276. <style>
  1277. body {
  1278. background: #1f2023 !important;
  1279. }
  1280. td, .forum > td {
  1281. color: ${mainTextColor} !important;
  1282. background-image: none !important;
  1283. }
  1284. font {
  1285. color: ${mainTextColor} !important;
  1286. opacity: 0.65;
  1287. }
  1288. a, .forum > a {
  1289. color: ${mainTextColor} !important;
  1290. /*opacity: 0.87;*/
  1291. }
  1292. div {
  1293. color: #121212;
  1294. }
  1295. .txt {
  1296. color: ${mainTextColor};
  1297. /*opacity: 0.87;*/
  1298. }
  1299. .pi {
  1300. color: ${mainTextColor};
  1301. /*opacity: 0.87;*/
  1302. }
  1303. .wblight, .wb2, .wb td{
  1304. background-color: #2d2f34;
  1305. }
  1306. .wbwhite {
  1307. background-color: #383b40;
  1308. }
  1309. table.table3, table.table3 th {
  1310. background-color: #383b40;
  1311. }
  1312. .forum tr:not(.second) > td {
  1313. background-color: #383b40 !important;
  1314. }
  1315. table.forum tr.message_footer td {
  1316. background-color: #27292d !important;
  1317. }
  1318. .forum span, .second {
  1319. background-color: #2d2f34 !important;
  1320. }
  1321. #home_2 {
  1322. color: ${mainTextColor};
  1323. }
  1324. #hwm_for_zoom {
  1325. background-color: #27292d !important;
  1326. }
  1327. #hwm_for_zoom * {
  1328. color: ${mainTextColor};
  1329. }
  1330. .dark_seconds {
  1331. color: #a50909;
  1332. }
  1333. * {
  1334. border-color: #55565d !important;
  1335. }
  1336. table td.tlight {
  1337. background-color: #2d2f34 !important;
  1338. background-image: none;
  1339. }
  1340. table td.twhite {
  1341. background-color: #383b40 !important;
  1342. background-image: none;
  1343. }
  1344. #pa,#pd, #pp, #pk, #pl, #pm, #pi, #ap, #sc {
  1345. color: ${mainTextColor} !important;
  1346. }
  1347. </style>
  1348. `
  1349. }
  1350. })(window);