MWI TaskManager

sort all task in taskboard

// ==UserScript==
// @name         MWI TaskManager
// @namespace    http://tampermonkey.net/
// @version      0.16
// @description  sort all task in taskboard
// @author       shykai
// @match        https://www.milkywayidle.com/*
// @match        https://test.milkywayidle.com/*
// @icon         https://www.milkywayidle.com/favicon.svg
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

(function () {
    'use strict';

    //default config
    let globalConfig = {
        isBattleIcon: true,
        dungeonConfig: {
            "/actions/combat/chimerical_den": false,
            "/actions/combat/sinister_circus": false,
            "/actions/combat/enchanted_fortress": false,
        }
    };

    const globalConfigName = "MWITaskManager_globalConfig";
    function saveConfig() {
        GM_setValue(globalConfigName, JSON.stringify(globalConfig));
    }

    const savedConfig = GM_getValue(globalConfigName, null);
    if (savedConfig) {
        Object.assign(globalConfig, JSON.parse(savedConfig));
    }

    const taskBattleIndex = 99; //Battle at bottom
    const taskOrderIndex = {
        Milking: 1,
        Foraging: 2,
        Woodcutting: 3,
        Cheesesmithing: 4,
        Crafting: 5,
        Tailoring: 6,
        Cooking: 7,
        Brewing: 8,
        Alchemy: 9,
        Enhancing: 10,
        Defeat: taskBattleIndex, //Battle at bottom
    };
    const taskOrderIndex_CN = {
        挤奶: 1,
        采摘: 2,
        伐木: 3,
        奶酪锻造: 4,
        制作: 5,
        缝纫: 6,
        烹饪: 7,
        冲泡: 8,
        炼金: 9,
        强化: 10,
        击败: taskBattleIndex, //Battle at bottom
    };

    const allMonster = {
        "/monsters/abyssal_imp": {
            "en": "Abyssal Imp",
            "cn": "深渊小鬼",
            "zone": "/actions/combat/infernal_abyss",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 11
        },
        "/monsters/aquahorse": {
            "en": "Aquahorse",
            "cn": "水马",
            "zone": "/actions/combat/aqua_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 3
        },
        "/monsters/black_bear": {
            "en": "Black Bear",
            "cn": "黑熊",
            "zone": "/actions/combat/bear_with_it",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 8
        },
        "/monsters/gobo_boomy": {
            "en": "Boomy",
            "cn": "轰轰",
            "zone": "/actions/combat/gobo_planet",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 5
        },
        "/monsters/butterjerry": {
            "en": "Butterjerry",
            "cn": "蝶鼠",
            "zone": "",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": -1
        },
        "/monsters/centaur_archer": {
            "en": "Centaur Archer",
            "cn": "半人马弓箭手",
            "zone": "/actions/combat/jungle_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 4
        },
        "/monsters/chronofrost_sorcerer": {
            "en": "Chronofrost Sorcerer",
            "cn": "霜时巫师",
            "zone": "/actions/combat/sorcerers_tower",
            "sortIndex": 7
        },
        "/monsters/crystal_colossus": {
            "en": "Crystal Colossus",
            "cn": "水晶巨像",
            "zone": "/actions/combat/golem_cave",
            "sortIndex": 9
        },
        "/monsters/demonic_overlord": {
            "en": "Demonic Overlord",
            "cn": "恶魔霸主",
            "zone": "/actions/combat/infernal_abyss",
            "sortIndex": 11
        },
        "/monsters/dusk_revenant": {
            "en": "Dusk Revenant",
            "cn": "黄昏亡灵",
            "zone": "/actions/combat/twilight_zone",
            "sortIndex": 10
        },
        "/monsters/elementalist": {
            "en": "Elementalist",
            "cn": "元素法师",
            "zone": "/actions/combat/sorcerers_tower",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 7
        },
        "/monsters/enchanted_pawn": {
            "en": "Enchanted Pawn",
            "cn": "秘法之兵",
            "zone": "",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": -1
        },
        "/monsters/eye": {
            "en": "Eye",
            "cn": "独眼",
            "zone": "/actions/combat/planet_of_the_eyes",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 6
        },
        "/monsters/eyes": {
            "en": "Eyes",
            "cn": "叠眼",
            "zone": "/actions/combat/planet_of_the_eyes",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 6
        },
        "/monsters/flame_sorcerer": {
            "en": "Flame Sorcerer",
            "cn": "火焰巫师",
            "zone": "/actions/combat/sorcerers_tower",
            "dungeon": [
                "/actions/combat/enchanted_fortress",
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 7
        },
        "/monsters/fly": {
            "en": "Fly",
            "cn": "苍蝇",
            "zone": "/actions/combat/smelly_planet",
            "sortIndex": 1
        },
        "/monsters/frog": {
            "en": "Frogger",
            "cn": "青蛙",
            "zone": "/actions/combat/swamp_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 2
        },
        "/monsters/sea_snail": {
            "en": "Gary",
            "cn": "蜗牛",
            "zone": "/actions/combat/aqua_planet",
            "sortIndex": 3
        },
        "/monsters/giant_shoebill": {
            "en": "Giant Shoebill",
            "cn": "鲸头鹳",
            "zone": "/actions/combat/swamp_planet",
            "sortIndex": 2
        },
        "/monsters/gobo_chieftain": {
            "en": "Gobo Chieftain",
            "cn": "哥布林酋长",
            "zone": "/actions/combat/gobo_planet",
            "sortIndex": 5
        },
        "/monsters/granite_golem": {
            "en": "Granite Golem",
            "cn": "花岗魔像",
            "zone": "/actions/combat/golem_cave",
            "sortIndex": 9
        },
        "/monsters/grizzly_bear": {
            "en": "Grizzly Bear",
            "cn": "棕熊",
            "zone": "/actions/combat/bear_with_it",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 8
        },
        "/monsters/gummy_bear": {
            "en": "Gummy Bear",
            "cn": "软糖熊",
            "zone": "/actions/combat/bear_with_it",
            "dungeon": [
                "/actions/combat/chimerical_den",
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 8
        },
        "/monsters/crab": {
            "en": "I Pinch",
            "cn": "螃蟹",
            "zone": "/actions/combat/aqua_planet",
            "sortIndex": 3
        },
        "/monsters/ice_sorcerer": {
            "en": "Ice Sorcerer",
            "cn": "冰霜巫师",
            "zone": "/actions/combat/sorcerers_tower",
            "dungeon": [
                "/actions/combat/enchanted_fortress",
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 7
        },
        "/monsters/infernal_warlock": {
            "en": "Infernal Warlock",
            "cn": "地狱术士",
            "zone": "/actions/combat/infernal_abyss",
            "sortIndex": 11
        },
        "/monsters/jackalope": {
            "en": "Jackalope",
            "cn": "鹿角兔",
            "zone": "",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": -1
        },
        "/monsters/rat": {
            "en": "Jerry",
            "cn": "杰瑞",
            "zone": "/actions/combat/smelly_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 1
        },
        "/monsters/jungle_sprite": {
            "en": "Jungle Sprite",
            "cn": "丛林精灵",
            "zone": "/actions/combat/jungle_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 4
        },
        "/monsters/luna_empress": {
            "en": "Luna Empress",
            "cn": "月神之蝶",
            "zone": "/actions/combat/jungle_planet",
            "sortIndex": 4
        },
        "/monsters/magnetic_golem": {
            "en": "Magnetic Golem",
            "cn": "磁力魔像",
            "zone": "/actions/combat/golem_cave",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 9
        },
        "/monsters/marine_huntress": {
            "en": "Marine Huntress",
            "cn": "海洋猎手",
            "zone": "/actions/combat/aqua_planet",
            "sortIndex": 3
        },
        "/monsters/myconid": {
            "en": "Myconid",
            "cn": "蘑菇人",
            "zone": "/actions/combat/jungle_planet",
            "sortIndex": 4
        },
        "/monsters/nom_nom": {
            "en": "Nom Nom",
            "cn": "咬咬鱼",
            "zone": "/actions/combat/aqua_planet",
            "sortIndex": 3
        },
        "/monsters/novice_sorcerer": {
            "en": "Novice Sorcerer",
            "cn": "新手巫师",
            "zone": "/actions/combat/sorcerers_tower",
            "dungeon": [
                "/actions/combat/enchanted_fortress",
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 7
        },
        "/monsters/panda": {
            "en": "Panda",
            "cn": "熊猫",
            "zone": "/actions/combat/bear_with_it",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 8
        },
        "/monsters/polar_bear": {
            "en": "Polar Bear",
            "cn": "北极熊",
            "zone": "/actions/combat/bear_with_it",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 8
        },
        "/monsters/porcupine": {
            "en": "Porcupine",
            "cn": "豪猪",
            "zone": "/actions/combat/smelly_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 1
        },
        "/monsters/rabid_rabbit": {
            "en": "Rabid Rabbit",
            "cn": "疯魔兔",
            "zone": "",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": -1
        },
        "/monsters/red_panda": {
            "en": "Red Panda",
            "cn": "小熊猫",
            "zone": "/actions/combat/bear_with_it",
            "sortIndex": 8
        },
        "/monsters/alligator": {
            "en": "Sherlock",
            "cn": "夏洛克",
            "zone": "/actions/combat/swamp_planet",
            "sortIndex": 2
        },
        "/monsters/gobo_shooty": {
            "en": "Shooty",
            "cn": "咻咻",
            "zone": "/actions/combat/gobo_planet",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 5
        },
        "/monsters/skunk": {
            "en": "Skunk",
            "cn": "臭鼬",
            "zone": "/actions/combat/smelly_planet",
            "sortIndex": 1
        },
        "/monsters/gobo_slashy": {
            "en": "Slashy",
            "cn": "砍砍",
            "zone": "/actions/combat/gobo_planet",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 5
        },
        "/monsters/slimy": {
            "en": "Slimy",
            "cn": "史莱姆",
            "zone": "/actions/combat/smelly_planet",
            "sortIndex": 1
        },
        "/monsters/gobo_smashy": {
            "en": "Smashy",
            "cn": "锤锤",
            "zone": "/actions/combat/gobo_planet",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 5
        },
        "/monsters/soul_hunter": {
            "en": "Soul Hunter",
            "cn": "灵魂猎手",
            "zone": "/actions/combat/infernal_abyss",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 11
        },
        "/monsters/gobo_stabby": {
            "en": "Stabby",
            "cn": "刺刺",
            "zone": "/actions/combat/gobo_planet",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 5
        },
        "/monsters/stalactite_golem": {
            "en": "Stalactite Golem",
            "cn": "钟乳石魔像",
            "zone": "/actions/combat/golem_cave",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 9
        },
        "/monsters/swampy": {
            "en": "Swampy",
            "cn": "沼泽虫",
            "zone": "/actions/combat/swamp_planet",
            "dungeon": [
                "/actions/combat/chimerical_den"
            ],
            "sortIndex": 2
        },
        "/monsters/the_watcher": {
            "en": "The Watcher",
            "cn": "观察者",
            "zone": "/actions/combat/planet_of_the_eyes",
            "sortIndex": 6
        },
        "/monsters/snake": {
            "en": "Thnake",
            "cn": "蛇",
            "zone": "/actions/combat/swamp_planet",
            "sortIndex": 2
        },
        "/monsters/treant": {
            "en": "Treant",
            "cn": "树人",
            "zone": "/actions/combat/jungle_planet",
            "sortIndex": 4
        },
        "/monsters/turtle": {
            "en": "Turuto",
            "cn": "忍者龟",
            "zone": "/actions/combat/aqua_planet",
            "sortIndex": 3
        },
        "/monsters/vampire": {
            "en": "Vampire",
            "cn": "吸血鬼",
            "zone": "/actions/combat/twilight_zone",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 10
        },
        "/monsters/veyes": {
            "en": "Veyes",
            "cn": "复眼",
            "zone": "/actions/combat/planet_of_the_eyes",
            "dungeon": [
                "/actions/combat/enchanted_fortress"
            ],
            "sortIndex": 6
        },
        "/monsters/werewolf": {
            "en": "Werewolf",
            "cn": "狼人",
            "zone": "/actions/combat/twilight_zone",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 10
        },
        "/monsters/zombie": {
            "en": "Zombie",
            "cn": "僵尸",
            "zone": "/actions/combat/twilight_zone",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": 10
        },
        "/monsters/zombie_bear": {
            "en": "Zombie Bear",
            "cn": "僵尸熊",
            "zone": "",
            "dungeon": [
                "/actions/combat/sinister_circus"
            ],
            "sortIndex": -1
        }
    };

    function getTaskDetailFromTaskName(fullTaskName) {
        var taskType = -1;
        var taskName = "";

        if (/^(.+) - (.+)$/.test(fullTaskName)) {
            let res = /^(.+) - (.+)$/.exec(fullTaskName);
            if (res[1] in taskOrderIndex) {
                taskType = taskOrderIndex[res[1]];
            }
            else if (res[1] in taskOrderIndex_CN) {
                taskType = taskOrderIndex_CN[res[1]];
            }
            taskName = res[2];
        }
        if (taskType == -1) console.log("Task Parse error", fullTaskName);

        return { taskType, taskName };
    }

    function getHridFromMonsterName(name) {
        for (let key in allMonster) {
            if (allMonster[key].en === name || allMonster[key].cn === name) {
                return key;
            }
        }
        console.log("Monster not found", name);
        return null;
    }
    function getMapIndexFromMonsterName(name) {
        const key = getHridFromMonsterName(name);
        if (!key) {
            return -1;
        }
        return allMonster[key].sortIndex;
    }

    function getTaskDetailFromElement(ele) {
        const div = ele.querySelector("div.RandomTask_name__1hl1b");

        const translatedfrom = div.getAttribute("script_translatedfrom"); //adapt old zhCN Script
        if (translatedfrom) {
            return getTaskDetailFromTaskName(translatedfrom);
        }

        const fullTaskName = Array.from(div.childNodes).find(node => node.nodeType === Node.TEXT_NODE).textContent.trim();
        return getTaskDetailFromTaskName(fullTaskName);
    }

    function compareFn(a, b) {
        var { taskType: a_TypeIndex, taskName: a_taskName } = getTaskDetailFromElement(a);

        var { taskType: b_TypeIndex, taskName: b_TaskName } = getTaskDetailFromElement(b);

        if (a_TypeIndex === taskBattleIndex && b_TypeIndex === taskBattleIndex) {
            var a_MapIndex = getMapIndexFromMonsterName(a_taskName);
            var b_MapIndex = getMapIndexFromMonsterName(b_TaskName);

            if (a_MapIndex != b_MapIndex) {
                return (a_MapIndex > b_MapIndex ? 1 : -1);
            }
        }

        if (a_TypeIndex == b_TypeIndex) {
            return a_taskName == b_TaskName ? 0
            : (a_taskName > b_TaskName ? 1 : -1);
        }

        return a_TypeIndex > b_TypeIndex ? 1 : -1;
    }

    function addIconToTask(div) {
        var { taskType, taskName } = getTaskDetailFromElement(div);

        if (taskType != taskBattleIndex) {
            return;
        }

        const monsterHrid = getHridFromMonsterName(taskName);
        if (!monsterHrid) {
            return;
        }

        var offset = 5; // 5% from left and each 30% width
        const isShowDungeon = Object.values(globalConfig.dungeonConfig).filter(Boolean).length > 0;
        if (!isShowDungeon) {
            offset = 50;
        }

        const backgroundDiv = document.createElement('div');
        backgroundDiv.id = "MonsterIcon";
        backgroundDiv.style.position = 'absolute';
        backgroundDiv.style.left = `${offset}%`; offset += 30;
        backgroundDiv.style.width = '30%';
        backgroundDiv.style.height = '100%';
        backgroundDiv.style.opacity = '0.3';

        const monsterName = monsterHrid.split("/").pop();
        const svgContent = `<svg width="100%" height="100%"><use href="/static/media/combat_monsters_sprite.395438a8.svg#${monsterName}"></use></svg>`;
        backgroundDiv.innerHTML = svgContent;

        div.appendChild(backgroundDiv);


        const dungeonMap = allMonster[monsterHrid]?.dungeon;
        if (isShowDungeon && dungeonMap) {
            Object.keys(globalConfig.dungeonConfig).filter(dungeon => globalConfig.dungeonConfig[dungeon]).forEach(dungeon => {
                if (dungeonMap.includes(dungeon)) {
                    const dungeonDiv = document.createElement('div');
                    dungeonDiv.id = "DungeonIcon";
                    dungeonDiv.style.position = 'absolute';
                    dungeonDiv.style.left = `${offset}%`; offset += 30;
                    dungeonDiv.style.width = '30%';
                    dungeonDiv.style.height = '100%';
                    dungeonDiv.style.opacity = '0.3';

                    const dungeonName = dungeon.split("/").pop();
                    const svgContent = `<svg width="100%" height="100%"><use href="/static/media/actions_sprite.8d5ceb4a.svg#${dungeonName}"></use></svg>`;
                    dungeonDiv.innerHTML = svgContent;

                    div.appendChild(dungeonDiv);
                }
            })
        }

        // fix button style
        div.style.position = 'relative';
        div.querySelector(".RandomTask_content__VVQva").style.zIndex = 1;
        div.querySelectorAll(".Item_item__2De2O").forEach(node => node.style.backgroundColor = "transparent");

    }

    function updateIconByConfig() {
        const battleIcon = document.querySelector("#BattleIcon");
        if (battleIcon) {
            if (globalConfig.isBattleIcon) {
                battleIcon.style.opacity = '1';
                battleIcon.querySelector("#taskCount").style.display = 'inline';
            } else {
                battleIcon.style.opacity = '0.3';
                battleIcon.querySelector("#taskCount").style.display = 'none';
            }
        }

        Object.keys(globalConfig.dungeonConfig).forEach(dungeon => {
            const dungeonIcon = document.querySelector(`#${dungeon.split("/").pop()}`);
            if (dungeonIcon) {
                if (globalConfig.isBattleIcon && globalConfig.dungeonConfig[dungeon]) {
                    dungeonIcon.style.opacity = '1';
                    dungeonIcon.querySelector("#taskCount").style.display = 'inline';
                } else {
                    dungeonIcon.style.opacity = '0.3';
                    dungeonIcon.querySelector("#taskCount").style.display = 'none';
                }
            }
        });
    }

    function createIcon(id,href) {

        // battle icon
        const div = document.createElement("div");
        div.id = id;
        div.style.height = "100%"; // 设置高度

        const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        svg.setAttribute("role", "img");
        svg.setAttribute("aria-label", "Combat");
        svg.setAttribute("class", "Icon_icon__2LtL_ Icon_xtiny__331pI Icon_inline__1Idwv");
        svg.setAttribute("width", "100%");
        svg.setAttribute("height", "100%");
        svg.style.margin = "1px";

        const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
        use.setAttribute("href", href);
        svg.appendChild(use);

        const divCount = document.createElement("span");
        divCount.id = "taskCount";
        divCount.textContent = "";

        div.appendChild(svg);
        div.appendChild(divCount);

        // div onclick change config
        div.addEventListener("click", function (evt) {
            if (id === "BattleIcon") {
                globalConfig.isBattleIcon = !globalConfig.isBattleIcon;
            } else {
                let configkey = Object.keys(globalConfig.dungeonConfig).find(key => key.split("/").pop() === id);
                globalConfig.dungeonConfig[configkey] = !globalConfig.dungeonConfig[configkey];
            }
            saveConfig(); //auto save when click

            updateIconByConfig();

            //clean all checkers to refresh statics
            document.querySelectorAll("#taskChekerInCoin").forEach(checker => checker.id = null);
        });

        return div;
    }

    function addSortButtonAndStaticsBar(pannel) {
        const sortButton = document.createElement("button");
        sortButton.setAttribute("class", "Button_button__1Fe9z Button_small__3fqC7");
        sortButton.id = "TaskSort";
        sortButton.innerHTML = "TaskSort";
        sortButton.addEventListener("click", function (evt) {
            const list = document.querySelector("div.TasksPanel_taskList__2xh4k");
            [...list.querySelectorAll("div.RandomTask_randomTask__3B9fA")]
                .sort(compareFn)
                .forEach(node => list.appendChild(node));
        });
        pannel.appendChild(sortButton);

        // add statics bar
        const battleIcon = createIcon("BattleIcon", "/static/media/misc_sprite.426c5d78.svg#combat");
        pannel.appendChild(battleIcon);

        // add all dungeon icon
        Object.keys(globalConfig.dungeonConfig).forEach(dungeon => {
            const dungeonIcon = createIcon(dungeon.split("/").pop(), `/static/media/actions_sprite.8d5ceb4a.svg#${dungeon.split("/").pop()}`);
            pannel.appendChild(dungeonIcon);
        });
    }

    function optimizeForMobile(pannel) {
        if (/Mobi|Android/i.test(navigator.userAgent)) {
            const upgradeButton = pannel.querySelector("button.Button_button__1Fe9z.Button_small__3fqC7");
            if (upgradeButton) {
                upgradeButton.style.display = "none";
                console.log("hide upgrade button when mobile");
            }
        }
    }

    function refresh() {
        const pannel = document.querySelector("div.TasksPanel_taskSlotCount__nfhgS");
        if (pannel) {
            let sortButton = pannel.querySelector("#TaskSort");
            if (!sortButton) {
                optimizeForMobile(pannel);
                addSortButtonAndStaticsBar(pannel);
                updateIconByConfig();
            }
        }
        else {
            return; //not in task board
        }

        let needRefreshTaskStatics = false;
        const taskNodes = document.querySelectorAll("div.TasksPanel_taskList__2xh4k div.RandomTask_randomTask__3B9fA");
        for (let node of taskNodes) {
            const coinDiv = node.querySelector(".Item_count__1HVvv");
            if (coinDiv && !coinDiv.querySelector("#taskChekerInCoin")) {
                needRefreshTaskStatics = true;

                //remove old and add new icon
                const oldIcon = node.querySelector("#MonsterIcon");
                if (oldIcon) {
                    oldIcon.remove();
                }
                const oldDungeonIcons = node.querySelectorAll("#DungeonIcon");
                oldDungeonIcons.forEach(icon => icon.remove());

                if (globalConfig.isBattleIcon) {
                    addIconToTask(node);
                }

                //add checker
                const checker = document.createElement("div");
                checker.id = "taskChekerInCoin";
                coinDiv.appendChild(checker);
            }
        }

        if (needRefreshTaskStatics)
        {
            const battleIcon = document.querySelector("#BattleIcon #taskCount");
            if (battleIcon) {
                const battleCount = [...document.querySelectorAll("div.RandomTask_randomTask__3B9fA")].filter(node => node.querySelector("#MonsterIcon")).length;
                battleIcon.textContent = battleCount > 0 ? `*${battleCount}` : '';
            }

            Object.keys(globalConfig.dungeonConfig).forEach(dungeon => {
                const dungeonIcon = document.querySelector(`#${dungeon.split("/").pop()} #taskCount`);
                if (dungeonIcon) {
                    const dungeonCount = [...document.querySelectorAll("div.RandomTask_randomTask__3B9fA")].filter(node => {
                        const dungeonIcons = node.querySelectorAll("#DungeonIcon use");
                        return Array.from(dungeonIcons).some(icon => icon.getAttribute("href").includes(dungeon.split("/").pop()));
                    }).length;
                    dungeonIcon.textContent = dungeonCount > 0 ? `*${dungeonCount}` : '';
                }
            });
        }
    }

    const config = { attributes: true, childList: true, subtree: true };

    const observer = new MutationObserver(function (mutationsList, observer) {
        refresh();
    });

    observer.observe(document, config);

})();

QingJ © 2025

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