MWI TaskManager

sort all task in taskpanel

当前为 2025-03-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name MWI TaskManager
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.13
  5. // @description sort all task in taskpanel
  6. // @author shykai
  7. // @match https://www.milkywayidle.com/*
  8. // @match https://test.milkywayidle.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=milkywayidle.com
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16.  
  17. //default config
  18. let globalConfig = {
  19. isBattleIcon: true,
  20. dungeonConfig: {
  21. "/actions/combat/chimerical_den": false,
  22. "/actions/combat/sinister_circus": false,
  23. "/actions/combat/enchanted_fortress": false,
  24. }
  25. };
  26.  
  27. const globalConfigName = "MWITaskManager_globalConfig";
  28. function saveConfig() {
  29. GM_setValue(globalConfigName, JSON.stringify(globalConfig));
  30. }
  31.  
  32. const savedConfig = GM_getValue(globalConfigName, null);
  33. if (savedConfig) {
  34. Object.assign(globalConfig, JSON.parse(savedConfig));
  35. }
  36.  
  37. const taskBattleIndex = 99; //Battle at bottom
  38. const taskOrderIndex = {
  39. Milking: 1,
  40. Foraging: 2,
  41. Woodcutting: 3,
  42. Cheesesmithing: 4,
  43. Crafting: 5,
  44. Tailoring: 6,
  45. Cooking: 7,
  46. Brewing: 8,
  47. Alchemy: 9,
  48. Enhancing: 10,
  49. Defeat: taskBattleIndex, //Battle at bottom
  50. };
  51. const taskOrderIndex_CN = {
  52. 挤奶: 1,
  53. 采摘: 2,
  54. 伐木: 3,
  55. 奶酪锻造: 4,
  56. 制作: 5,
  57. 缝纫: 6,
  58. 烹饪: 7,
  59. 冲泡: 8,
  60. 炼金: 9,
  61. 强化: 10,
  62. 击败: taskBattleIndex, //Battle at bottom
  63. };
  64.  
  65. const allMonster = {
  66. "/monsters/abyssal_imp": {
  67. "en": "Abyssal Imp",
  68. "cn": "深渊小鬼",
  69. "zone": "/actions/combat/infernal_abyss",
  70. "dungeon": [
  71. "/actions/combat/enchanted_fortress"
  72. ],
  73. "sortIndex": 11
  74. },
  75. "/monsters/aquahorse": {
  76. "en": "Aquahorse",
  77. "cn": "水马",
  78. "zone": "/actions/combat/aqua_planet",
  79. "dungeon": [
  80. "/actions/combat/chimerical_den"
  81. ],
  82. "sortIndex": 3
  83. },
  84. "/monsters/black_bear": {
  85. "en": "Black Bear",
  86. "cn": "黑熊",
  87. "zone": "/actions/combat/bear_with_it",
  88. "dungeon": [
  89. "/actions/combat/sinister_circus"
  90. ],
  91. "sortIndex": 8
  92. },
  93. "/monsters/gobo_boomy": {
  94. "en": "Boomy",
  95. "cn": "轰轰",
  96. "zone": "/actions/combat/gobo_planet",
  97. "dungeon": [
  98. "/actions/combat/sinister_circus"
  99. ],
  100. "sortIndex": 5
  101. },
  102. "/monsters/butterjerry": {
  103. "en": "Butterjerry",
  104. "cn": "蝶鼠",
  105. "zone": "",
  106. "dungeon": [
  107. "/actions/combat/chimerical_den"
  108. ],
  109. "sortIndex": -1
  110. },
  111. "/monsters/centaur_archer": {
  112. "en": "Centaur Archer",
  113. "cn": "半人马弓箭手",
  114. "zone": "/actions/combat/jungle_planet",
  115. "dungeon": [
  116. "/actions/combat/chimerical_den"
  117. ],
  118. "sortIndex": 4
  119. },
  120. "/monsters/chronofrost_sorcerer": {
  121. "en": "Chronofrost Sorcerer",
  122. "cn": "霜时巫师",
  123. "zone": "/actions/combat/sorcerers_tower",
  124. "sortIndex": 7
  125. },
  126. "/monsters/crystal_colossus": {
  127. "en": "Crystal Colossus",
  128. "cn": "水晶巨像",
  129. "zone": "/actions/combat/golem_cave",
  130. "sortIndex": 9
  131. },
  132. "/monsters/demonic_overlord": {
  133. "en": "Demonic Overlord",
  134. "cn": "恶魔霸主",
  135. "zone": "/actions/combat/infernal_abyss",
  136. "sortIndex": 11
  137. },
  138. "/monsters/dusk_revenant": {
  139. "en": "Dusk Revenant",
  140. "cn": "黄昏亡灵",
  141. "zone": "/actions/combat/twilight_zone",
  142. "sortIndex": 10
  143. },
  144. "/monsters/elementalist": {
  145. "en": "Elementalist",
  146. "cn": "元素法师",
  147. "zone": "/actions/combat/sorcerers_tower",
  148. "dungeon": [
  149. "/actions/combat/sinister_circus"
  150. ],
  151. "sortIndex": 7
  152. },
  153. "/monsters/enchanted_pawn": {
  154. "en": "Enchanted Pawn",
  155. "cn": "秘法之兵",
  156. "zone": "",
  157. "dungeon": [
  158. "/actions/combat/enchanted_fortress"
  159. ],
  160. "sortIndex": -1
  161. },
  162. "/monsters/eye": {
  163. "en": "Eye",
  164. "cn": "独眼",
  165. "zone": "/actions/combat/planet_of_the_eyes",
  166. "dungeon": [
  167. "/actions/combat/enchanted_fortress"
  168. ],
  169. "sortIndex": 6
  170. },
  171. "/monsters/eyes": {
  172. "en": "Eyes",
  173. "cn": "叠眼",
  174. "zone": "/actions/combat/planet_of_the_eyes",
  175. "dungeon": [
  176. "/actions/combat/enchanted_fortress"
  177. ],
  178. "sortIndex": 6
  179. },
  180. "/monsters/flame_sorcerer": {
  181. "en": "Flame Sorcerer",
  182. "cn": "火焰巫师",
  183. "zone": "/actions/combat/sorcerers_tower",
  184. "dungeon": [
  185. "/actions/combat/enchanted_fortress",
  186. "/actions/combat/sinister_circus"
  187. ],
  188. "sortIndex": 7
  189. },
  190. "/monsters/fly": {
  191. "en": "Fly",
  192. "cn": "苍蝇",
  193. "zone": "/actions/combat/smelly_planet",
  194. "sortIndex": 1
  195. },
  196. "/monsters/frog": {
  197. "en": "Frogger",
  198. "cn": "青蛙",
  199. "zone": "/actions/combat/swamp_planet",
  200. "dungeon": [
  201. "/actions/combat/chimerical_den"
  202. ],
  203. "sortIndex": 2
  204. },
  205. "/monsters/sea_snail": {
  206. "en": "Gary",
  207. "cn": "蜗牛",
  208. "zone": "/actions/combat/aqua_planet",
  209. "sortIndex": 3
  210. },
  211. "/monsters/giant_shoebill": {
  212. "en": "Giant Shoebill",
  213. "cn": "鲸头鹳",
  214. "zone": "/actions/combat/swamp_planet",
  215. "sortIndex": 2
  216. },
  217. "/monsters/gobo_chieftain": {
  218. "en": "Gobo Chieftain",
  219. "cn": "哥布林酋长",
  220. "zone": "/actions/combat/gobo_planet",
  221. "sortIndex": 5
  222. },
  223. "/monsters/granite_golem": {
  224. "en": "Granite Golem",
  225. "cn": "花岗魔像",
  226. "zone": "/actions/combat/golem_cave",
  227. "sortIndex": 9
  228. },
  229. "/monsters/grizzly_bear": {
  230. "en": "Grizzly Bear",
  231. "cn": "棕熊",
  232. "zone": "/actions/combat/bear_with_it",
  233. "dungeon": [
  234. "/actions/combat/sinister_circus"
  235. ],
  236. "sortIndex": 8
  237. },
  238. "/monsters/gummy_bear": {
  239. "en": "Gummy Bear",
  240. "cn": "软糖熊",
  241. "zone": "/actions/combat/bear_with_it",
  242. "dungeon": [
  243. "/actions/combat/chimerical_den",
  244. "/actions/combat/sinister_circus"
  245. ],
  246. "sortIndex": 8
  247. },
  248. "/monsters/crab": {
  249. "en": "I Pinch",
  250. "cn": "螃蟹",
  251. "zone": "/actions/combat/aqua_planet",
  252. "sortIndex": 3
  253. },
  254. "/monsters/ice_sorcerer": {
  255. "en": "Ice Sorcerer",
  256. "cn": "冰霜巫师",
  257. "zone": "/actions/combat/sorcerers_tower",
  258. "dungeon": [
  259. "/actions/combat/enchanted_fortress",
  260. "/actions/combat/sinister_circus"
  261. ],
  262. "sortIndex": 7
  263. },
  264. "/monsters/infernal_warlock": {
  265. "en": "Infernal Warlock",
  266. "cn": "地狱术士",
  267. "zone": "/actions/combat/infernal_abyss",
  268. "sortIndex": 11
  269. },
  270. "/monsters/jackalope": {
  271. "en": "Jackalope",
  272. "cn": "鹿角兔",
  273. "zone": "",
  274. "dungeon": [
  275. "/actions/combat/chimerical_den"
  276. ],
  277. "sortIndex": -1
  278. },
  279. "/monsters/rat": {
  280. "en": "Jerry",
  281. "cn": "杰瑞",
  282. "zone": "/actions/combat/smelly_planet",
  283. "dungeon": [
  284. "/actions/combat/chimerical_den"
  285. ],
  286. "sortIndex": 1
  287. },
  288. "/monsters/jungle_sprite": {
  289. "en": "Jungle Sprite",
  290. "cn": "丛林精灵",
  291. "zone": "/actions/combat/jungle_planet",
  292. "dungeon": [
  293. "/actions/combat/chimerical_den"
  294. ],
  295. "sortIndex": 4
  296. },
  297. "/monsters/luna_empress": {
  298. "en": "Luna Empress",
  299. "cn": "月神之蝶",
  300. "zone": "/actions/combat/jungle_planet",
  301. "sortIndex": 4
  302. },
  303. "/monsters/magnetic_golem": {
  304. "en": "Magnetic Golem",
  305. "cn": "磁力魔像",
  306. "zone": "/actions/combat/golem_cave",
  307. "dungeon": [
  308. "/actions/combat/enchanted_fortress"
  309. ],
  310. "sortIndex": 9
  311. },
  312. "/monsters/marine_huntress": {
  313. "en": "Marine Huntress",
  314. "cn": "海洋猎手",
  315. "zone": "/actions/combat/aqua_planet",
  316. "sortIndex": 3
  317. },
  318. "/monsters/myconid": {
  319. "en": "Myconid",
  320. "cn": "蘑菇人",
  321. "zone": "/actions/combat/jungle_planet",
  322. "sortIndex": 4
  323. },
  324. "/monsters/nom_nom": {
  325. "en": "Nom Nom",
  326. "cn": "咬咬鱼",
  327. "zone": "/actions/combat/aqua_planet",
  328. "sortIndex": 3
  329. },
  330. "/monsters/novice_sorcerer": {
  331. "en": "Novice Sorcerer",
  332. "cn": "新手巫师",
  333. "zone": "/actions/combat/sorcerers_tower",
  334. "dungeon": [
  335. "/actions/combat/enchanted_fortress",
  336. "/actions/combat/sinister_circus"
  337. ],
  338. "sortIndex": 7
  339. },
  340. "/monsters/panda": {
  341. "en": "Panda",
  342. "cn": "熊猫",
  343. "zone": "/actions/combat/bear_with_it",
  344. "dungeon": [
  345. "/actions/combat/sinister_circus"
  346. ],
  347. "sortIndex": 8
  348. },
  349. "/monsters/polar_bear": {
  350. "en": "Polar Bear",
  351. "cn": "北极熊",
  352. "zone": "/actions/combat/bear_with_it",
  353. "dungeon": [
  354. "/actions/combat/sinister_circus"
  355. ],
  356. "sortIndex": 8
  357. },
  358. "/monsters/porcupine": {
  359. "en": "Porcupine",
  360. "cn": "豪猪",
  361. "zone": "/actions/combat/smelly_planet",
  362. "dungeon": [
  363. "/actions/combat/chimerical_den"
  364. ],
  365. "sortIndex": 1
  366. },
  367. "/monsters/rabid_rabbit": {
  368. "en": "Rabid Rabbit",
  369. "cn": "疯魔兔",
  370. "zone": "",
  371. "dungeon": [
  372. "/actions/combat/sinister_circus"
  373. ],
  374. "sortIndex": -1
  375. },
  376. "/monsters/red_panda": {
  377. "en": "Red Panda",
  378. "cn": "小熊猫",
  379. "zone": "/actions/combat/bear_with_it",
  380. "sortIndex": 8
  381. },
  382. "/monsters/alligator": {
  383. "en": "Sherlock",
  384. "cn": "夏洛克",
  385. "zone": "/actions/combat/swamp_planet",
  386. "sortIndex": 2
  387. },
  388. "/monsters/gobo_shooty": {
  389. "en": "Shooty",
  390. "cn": "咻咻",
  391. "zone": "/actions/combat/gobo_planet",
  392. "dungeon": [
  393. "/actions/combat/sinister_circus"
  394. ],
  395. "sortIndex": 5
  396. },
  397. "/monsters/skunk": {
  398. "en": "Skunk",
  399. "cn": "臭鼬",
  400. "zone": "/actions/combat/smelly_planet",
  401. "sortIndex": 1
  402. },
  403. "/monsters/gobo_slashy": {
  404. "en": "Slashy",
  405. "cn": "砍砍",
  406. "zone": "/actions/combat/gobo_planet",
  407. "dungeon": [
  408. "/actions/combat/sinister_circus"
  409. ],
  410. "sortIndex": 5
  411. },
  412. "/monsters/slimy": {
  413. "en": "Slimy",
  414. "cn": "史莱姆",
  415. "zone": "/actions/combat/smelly_planet",
  416. "sortIndex": 1
  417. },
  418. "/monsters/gobo_smashy": {
  419. "en": "Smashy",
  420. "cn": "锤锤",
  421. "zone": "/actions/combat/gobo_planet",
  422. "dungeon": [
  423. "/actions/combat/sinister_circus"
  424. ],
  425. "sortIndex": 5
  426. },
  427. "/monsters/soul_hunter": {
  428. "en": "Soul Hunter",
  429. "cn": "灵魂猎手",
  430. "zone": "/actions/combat/infernal_abyss",
  431. "dungeon": [
  432. "/actions/combat/enchanted_fortress"
  433. ],
  434. "sortIndex": 11
  435. },
  436. "/monsters/gobo_stabby": {
  437. "en": "Stabby",
  438. "cn": "刺刺",
  439. "zone": "/actions/combat/gobo_planet",
  440. "dungeon": [
  441. "/actions/combat/sinister_circus"
  442. ],
  443. "sortIndex": 5
  444. },
  445. "/monsters/stalactite_golem": {
  446. "en": "Stalactite Golem",
  447. "cn": "钟乳石魔像",
  448. "zone": "/actions/combat/golem_cave",
  449. "dungeon": [
  450. "/actions/combat/enchanted_fortress"
  451. ],
  452. "sortIndex": 9
  453. },
  454. "/monsters/swampy": {
  455. "en": "Swampy",
  456. "cn": "沼泽虫",
  457. "zone": "/actions/combat/swamp_planet",
  458. "dungeon": [
  459. "/actions/combat/chimerical_den"
  460. ],
  461. "sortIndex": 2
  462. },
  463. "/monsters/the_watcher": {
  464. "en": "The Watcher",
  465. "cn": "观察者",
  466. "zone": "/actions/combat/planet_of_the_eyes",
  467. "sortIndex": 6
  468. },
  469. "/monsters/snake": {
  470. "en": "Thnake",
  471. "cn": "蛇",
  472. "zone": "/actions/combat/swamp_planet",
  473. "sortIndex": 2
  474. },
  475. "/monsters/treant": {
  476. "en": "Treant",
  477. "cn": "树人",
  478. "zone": "/actions/combat/jungle_planet",
  479. "sortIndex": 4
  480. },
  481. "/monsters/turtle": {
  482. "en": "Turuto",
  483. "cn": "忍者龟",
  484. "zone": "/actions/combat/aqua_planet",
  485. "sortIndex": 3
  486. },
  487. "/monsters/vampire": {
  488. "en": "Vampire",
  489. "cn": "吸血鬼",
  490. "zone": "/actions/combat/twilight_zone",
  491. "dungeon": [
  492. "/actions/combat/sinister_circus"
  493. ],
  494. "sortIndex": 10
  495. },
  496. "/monsters/veyes": {
  497. "en": "Veyes",
  498. "cn": "复眼",
  499. "zone": "/actions/combat/planet_of_the_eyes",
  500. "dungeon": [
  501. "/actions/combat/enchanted_fortress"
  502. ],
  503. "sortIndex": 6
  504. },
  505. "/monsters/werewolf": {
  506. "en": "Werewolf",
  507. "cn": "狼人",
  508. "zone": "/actions/combat/twilight_zone",
  509. "dungeon": [
  510. "/actions/combat/sinister_circus"
  511. ],
  512. "sortIndex": 10
  513. },
  514. "/monsters/zombie": {
  515. "en": "Zombie",
  516. "cn": "僵尸",
  517. "zone": "/actions/combat/twilight_zone",
  518. "dungeon": [
  519. "/actions/combat/sinister_circus"
  520. ],
  521. "sortIndex": 10
  522. },
  523. "/monsters/zombie_bear": {
  524. "en": "Zombie Bear",
  525. "cn": "僵尸熊",
  526. "zone": "",
  527. "dungeon": [
  528. "/actions/combat/sinister_circus"
  529. ],
  530. "sortIndex": -1
  531. }
  532. };
  533.  
  534. function getTaskDetailFromTaskName(fullTaskName) {
  535. var taskType = -1;
  536. var taskName = "";
  537.  
  538. if (/^(.+) - (.+)$/.test(fullTaskName)) {
  539. let res = /^(.+) - (.+)$/.exec(fullTaskName);
  540. if (res[1] in taskOrderIndex) {
  541. taskType = taskOrderIndex[res[1]];
  542. }
  543. else if (res[1] in taskOrderIndex_CN) {
  544. taskType = taskOrderIndex_CN[res[1]];
  545. }
  546. taskName = res[2];
  547. }
  548. if (taskType == -1) console.log(fullTaskName, taskType);
  549.  
  550. return { taskType, taskName };
  551. }
  552.  
  553. function getHridFromMonsterName(name) {
  554. for (let key in allMonster) {
  555. if (allMonster[key].en === name || allMonster[key].cn === name) {
  556. return key;
  557. }
  558. }
  559. console.log("Monster not found", name);
  560. return null;
  561. }
  562. function getMapIndexFromMonsterName(name) {
  563. const key = getHridFromMonsterName(name);
  564. if (!key) {
  565. return -1;
  566. }
  567. return allMonster[key].sortIndex;
  568. }
  569.  
  570. function getTaskDetailFromElement(ele) {
  571. const div = ele.querySelector("div.RandomTask_name__1hl1b");
  572.  
  573. const translatedfrom = div.getAttribute("script_translatedfrom"); //adapt old CN Script
  574. if (translatedfrom) {
  575. return getTaskDetailFromTaskName(translatedfrom);
  576. }
  577.  
  578. const fullTaskName = Array.from(div.childNodes).find(node => node.nodeType === Node.TEXT_NODE).textContent.trim();
  579. return getTaskDetailFromTaskName(fullTaskName);
  580. }
  581.  
  582. function compareFn(a, b) {
  583. var { taskType: a_TypeIndex, taskName: a_taskName } = getTaskDetailFromElement(a);
  584.  
  585. var { taskType: b_TypeIndex, taskName: b_TaskName } = getTaskDetailFromElement(b);
  586.  
  587. if (a_TypeIndex === taskBattleIndex && b_TypeIndex === taskBattleIndex) {
  588. var a_MapIndex = getMapIndexFromMonsterName(a_taskName);
  589. var b_MapIndex = getMapIndexFromMonsterName(b_TaskName);
  590.  
  591. if (a_MapIndex != b_MapIndex) {
  592. return (a_MapIndex > b_MapIndex ? 1 : -1);
  593. }
  594. }
  595.  
  596. if (a_TypeIndex == b_TypeIndex) {
  597. return a_taskName == b_TaskName ? 0
  598. : (a_taskName > b_TaskName ? 1 : -1);
  599. }
  600.  
  601. return a_TypeIndex > b_TypeIndex ? 1 : -1;
  602. }
  603.  
  604. function addIconToTask(div) {
  605. var { taskType, taskName } = getTaskDetailFromElement(div);
  606.  
  607. if (taskType != taskBattleIndex) {
  608. return;
  609. }
  610.  
  611. const monsterHrid = getHridFromMonsterName(taskName);
  612. if (!monsterHrid) {
  613. return;
  614. }
  615.  
  616. var offset = 5; // 5% from left and each 30% width
  617. const isShowDungeon = Object.values(globalConfig.dungeonConfig).filter(Boolean).length > 0;
  618. if (!isShowDungeon) {
  619. offset = 50;
  620. }
  621.  
  622. const backgroundDiv = document.createElement('div');
  623. backgroundDiv.id = "MonsterIcon";
  624. backgroundDiv.style.position = 'absolute';
  625. backgroundDiv.style.left = `${offset}%`; offset += 30;
  626. backgroundDiv.style.width = '30%';
  627. backgroundDiv.style.height = '100%';
  628. backgroundDiv.style.opacity = '0.3';
  629.  
  630. const monsterName = monsterHrid.split("/").pop();
  631. const svgContent = `<svg width="100%" height="100%"><use href="/static/media/combat_monsters_sprite.395438a8.svg#${monsterName}"></use></svg>`;
  632. backgroundDiv.innerHTML = svgContent;
  633.  
  634. div.appendChild(backgroundDiv);
  635.  
  636.  
  637. const dungeonMap = allMonster[monsterHrid]?.dungeon;
  638. if (isShowDungeon && dungeonMap) {
  639. Object.keys(globalConfig.dungeonConfig).filter(dungeon => globalConfig.dungeonConfig[dungeon]).forEach(dungeon => {
  640. if (dungeonMap.includes(dungeon)) {
  641. const dungeonDiv = document.createElement('div');
  642. dungeonDiv.id = "DungeonIcon";
  643. dungeonDiv.style.position = 'absolute';
  644. dungeonDiv.style.left = `${offset}%`; offset += 30;
  645. dungeonDiv.style.width = '30%';
  646. dungeonDiv.style.height = '100%';
  647. dungeonDiv.style.opacity = '0.3';
  648.  
  649. const dungeonName = dungeon.split("/").pop();
  650. const svgContent = `<svg width="100%" height="100%"><use href="/static/media/actions_sprite.8d5ceb4a.svg#${dungeonName}"></use></svg>`;
  651. dungeonDiv.innerHTML = svgContent;
  652.  
  653. div.appendChild(dungeonDiv);
  654. }
  655. })
  656. }
  657.  
  658. // fix button style
  659. div.style.position = 'relative';
  660. div.querySelector(".RandomTask_content__VVQva").style.zIndex = 1;
  661. div.querySelectorAll(".Item_item__2De2O").forEach(node => node.style.backgroundColor = "transparent");
  662.  
  663. }
  664.  
  665. function updateIconByConfig() {
  666. const battleIcon = document.querySelector("#BattleIcon");
  667. if (battleIcon) {
  668. if (globalConfig.isBattleIcon) {
  669. battleIcon.style.opacity = '1';
  670. battleIcon.querySelector("#taskCount").style.display = 'inline';
  671. } else {
  672. battleIcon.style.opacity = '0.3';
  673. battleIcon.querySelector("#taskCount").style.display = 'none';
  674. }
  675. }
  676.  
  677. Object.keys(globalConfig.dungeonConfig).forEach(dungeon => {
  678. const dungeonIcon = document.querySelector(`#${dungeon.split("/").pop()}`);
  679. if (dungeonIcon) {
  680. if (globalConfig.isBattleIcon && globalConfig.dungeonConfig[dungeon]) {
  681. dungeonIcon.style.opacity = '1';
  682. dungeonIcon.querySelector("#taskCount").style.display = 'inline';
  683. } else {
  684. dungeonIcon.style.opacity = '0.3';
  685. dungeonIcon.querySelector("#taskCount").style.display = 'none';
  686. }
  687. }
  688. });
  689. }
  690.  
  691. function createIcon(id,href) {
  692.  
  693. // battle icon
  694. const div = document.createElement("div");
  695. div.id = id;
  696. div.style.height = "100%"; // 设置高度
  697.  
  698. const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  699. svg.setAttribute("role", "img");
  700. svg.setAttribute("aria-label", "Combat");
  701. svg.setAttribute("class", "Icon_icon__2LtL_ Icon_xtiny__331pI Icon_inline__1Idwv");
  702. svg.setAttribute("width", "100%");
  703. svg.setAttribute("height", "100%");
  704. svg.style.margin = "1px";
  705.  
  706. const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
  707. use.setAttribute("href", href);
  708. svg.appendChild(use);
  709.  
  710. const divCount = document.createElement("span");
  711. divCount.id = "taskCount";
  712. divCount.textContent = "*0";
  713.  
  714. div.appendChild(svg);
  715. div.appendChild(divCount);
  716.  
  717. // div onclick change config
  718. div.addEventListener("click", function (evt) {
  719. if (id === "BattleIcon") {
  720. globalConfig.isBattleIcon = !globalConfig.isBattleIcon;
  721. } else {
  722. let configkey = Object.keys(globalConfig.dungeonConfig).find(key => key.split("/").pop() === id);
  723. globalConfig.dungeonConfig[configkey] = !globalConfig.dungeonConfig[configkey];
  724. }
  725. saveConfig(); //auto save when click
  726.  
  727. updateIconByConfig();
  728.  
  729. //clean all checkers
  730. document.querySelectorAll("#taskChekerInCoin").forEach(checker => checker.id = null);
  731. });
  732.  
  733. return div;
  734. }
  735.  
  736. function addSortButtonAndStaticsBar(pannel) {
  737. const sortButton = document.createElement("button");
  738. sortButton.setAttribute("class", "Button_button__1Fe9z Button_small__3fqC7");
  739. sortButton.id = "TaskSort";
  740. sortButton.innerHTML = "TaskSort";
  741. sortButton.addEventListener("click", function (evt) {
  742. const list = document.querySelector("div.TasksPanel_taskList__2xh4k");
  743. [...list.querySelectorAll("div.RandomTask_randomTask__3B9fA")]
  744. .sort(compareFn)
  745. .forEach(node => list.appendChild(node));
  746. });
  747. pannel.appendChild(sortButton);
  748.  
  749. // add statics bar
  750. const battleIcon = createIcon("BattleIcon", "/static/media/misc_sprite.426c5d78.svg#combat");
  751. pannel.appendChild(battleIcon);
  752.  
  753. // add all dungeon icon
  754. Object.keys(globalConfig.dungeonConfig).forEach(dungeon => {
  755. const dungeonIcon = createIcon(dungeon.split("/").pop(), `/static/media/actions_sprite.8d5ceb4a.svg#${dungeon.split("/").pop()}`);
  756. pannel.appendChild(dungeonIcon);
  757. });
  758. }
  759.  
  760.  
  761.  
  762. function refresh() {
  763. const pannel = document.querySelector("div.TasksPanel_taskSlotCount__nfhgS");
  764. if (pannel) {
  765. let sortButton = pannel.querySelector("#TaskSort");
  766. if (!sortButton) {
  767. addSortButtonAndStaticsBar(pannel);
  768. updateIconByConfig();
  769. }
  770. }
  771.  
  772. let needRefreshTaskStatics = false;
  773. const taskNodes = document.querySelectorAll("div.TasksPanel_taskList__2xh4k div.RandomTask_randomTask__3B9fA");
  774. for (let node of taskNodes) {
  775. const coinDiv = node.querySelector(".Item_count__1HVvv");
  776. if (coinDiv && !coinDiv.querySelector("#taskChekerInCoin")) {
  777. needRefreshTaskStatics = true;
  778.  
  779. //remove old and add new icon
  780. const oldIcon = node.querySelector("#MonsterIcon");
  781. if (oldIcon) {
  782. oldIcon.remove();
  783. }
  784. const oldDungeonIcons = node.querySelectorAll("#DungeonIcon");
  785. oldDungeonIcons.forEach(icon => icon.remove());
  786.  
  787. if (globalConfig.isBattleIcon) {
  788. addIconToTask(node);
  789. }
  790.  
  791. //add checker
  792. const checker = document.createElement("div");
  793. checker.id = "taskChekerInCoin";
  794. coinDiv.appendChild(checker);
  795. }
  796. }
  797.  
  798. if (needRefreshTaskStatics)
  799. {
  800. const battleIcon = document.querySelector("#BattleIcon #taskCount");
  801. if (battleIcon) {
  802. const battleCount = [...document.querySelectorAll("div.RandomTask_randomTask__3B9fA")].filter(node => node.querySelector("#MonsterIcon")).length;
  803. battleIcon.textContent = `*${battleCount}`;
  804. }
  805.  
  806. Object.keys(globalConfig.dungeonConfig).forEach(dungeon => {
  807. const dungeonIcon = document.querySelector(`#${dungeon.split("/").pop()} #taskCount`);
  808. if (dungeonIcon) {
  809. const dungeonCount = [...document.querySelectorAll("div.RandomTask_randomTask__3B9fA")].filter(node => {
  810. const dungeonIcons = node.querySelectorAll("#DungeonIcon use");
  811. return Array.from(dungeonIcons).some(icon => icon.getAttribute("href").includes(dungeon.split("/").pop()));
  812. }).length;
  813. dungeonIcon.textContent = `*${dungeonCount}`;
  814. }
  815. });
  816. }
  817. }
  818.  
  819. const config = { attributes: true, childList: true, subtree: true };
  820.  
  821. const observer = new MutationObserver(function (mutationsList, observer) {
  822. refresh();
  823. });
  824.  
  825. observer.observe(document, config);
  826.  
  827. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址