Greasy Fork is available in English.

B站游戏wiki ——支线任务完成标记

对H3任务标题添加【任务标记】、【内容折叠】功能,以便于了解自己完成的任务。对树桩、宝箱添加标记功能,记录领取状态。

// ==UserScript==
// @name         B站游戏wiki ——支线任务完成标记
// @namespace      https://greasyfork.org/users/3128
// @version       0.3.8
// @description    对H3任务标题添加【任务标记】、【内容折叠】功能,以便于了解自己完成的任务。对树桩、宝箱添加标记功能,记录领取状态。
// @author       极品小猫
// @match        https://wiki.biligame.com/yanyu/*
// @match        https://wiki.biligame.com/sr/*
// @exclude      https://wiki.biligame.com/yanyu/%E6%B8%B8%E6%88%8F%E6%94%AF%E7%BA%BF
// @require         https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM_addStyle
// @grant        GM_setClipboard
// @grant          GM_xmlhttpRequest
// @grant        unsafeWindow
// @grant        GM_notification
// @grant        GM_registerMenuCommand
// @license      MIT
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    let u=unsafeWindow,
        webHost=location.host.toLowerCase(),
        webPath=location.pathname;

    let wgConfig,
        wgGameName,
        wgPageName;
    let GM_Config, GM_Config_Task={},
        GMAPI={
            save(TableName, Data) {
                GM_setValue('update', new Date().getTime());
                if(arguments.length===0)
                    GM_setValue(wgGameName, GM_Config);
            }
        }

    if(webHost==='wiki.biligame.com') {
        wgConfig = u?.RLCONF || u?.mw?.config.get(),
            wgGameName = wgConfig?.wgGameName, //游戏Wiki名
            wgPageName = wgConfig?.wgPageName; //页面标题
        if(!wgPageName) alert(`加载基础数据失败,请刷新页面。`);

        GM_Config=GM_getValue(wgGameName, {});


        //转换 1.0 版本储存于 localStorage 的配置数据,使用 GM 存储 API 保存数据
        if(localStorage[wgPageName]) {
            GM_Config_Task=JSON.parse(localStorage[wgPageName]);
            GMAPI.save();
            delete localStorage[wgPageName];
        }
        if(!GM_Config[wgPageName]) {
            //转换 2.0 版本存储于 根节点 的配置数据,数据保存于 Wiki 对应的名称下,便于支持多 Wiki
            GM_Config_Task=GM_getValue(wgPageName, {});
            GM_Config[wgPageName]=GM_Config_Task;
            GM_deleteValue(wgPageName);
            GMAPI.save();
        } else {
            GM_Config_Task=GM_Config[wgPageName];
        }

        GM_addStyle(`
                input[title="任务完成标记"]{width:80px;height80px}
                /*解决信息盒子没有新信息时塌陷的问题*/
                .oo-ui-popupWidget-body {min-height:300px;}
                `);
        let Bind={
            InputClick(e) { // @Rank = 归类
                //console.log(this, e);
                if(e.data.Rank) {
                    if(!GM_Config_Task[e.data.Rank]) GM_Config_Task[e.data.Rank]={};
                    GM_Config_Task[e.data.Rank][e.data.key]=e.target.checked;
                }
                else GM_Config_Task[e.data.key]=e.target.checked;
                GMAPI.save();
            }
        }

        //专用功能
        switch(wgGameName) {
            case 'yanyu':
                //首页
                if(webPath.includes('%E9%A6%96%E9%A1%B5')) {
                    let hideModule=$('#游戏更新, #同人专区, #烟雨江湖WIKI, #游戏公告, #凤鸣书院, #其他作品')
                    //模块标题隐藏
                    hideModule.parent().hide();
                    //模块内容隐藏
                    hideModule.parent().next().hide();
                    $('#视频攻略').parentsUntil('small').parent().hide()
                    //答题辅助图片
                    $('a[title="答题辅助"]').parentsUntil('.sy-box-css, .sy-box-css-n').parent().hide();
                    $('.wikipoke img, img[alt="世界地图.png"]').hide();

                } else if(webPath.includes('%E7%AD%94%E9%A2%98%E8%BE%85%E5%8A%A9')) {
                    //答题辅助页面
                    let t=setInterval(function(e){
                        if($('.form-control.searcher-text').length>0) {
                            $('.form-control.searcher-text').focus(function(){
                                console.log($(this).select());
                                $(this).select();
                            });
                            clearInterval(t);
                        }
                    }, 1000);
                }

                //地图导航追加
                let MapModule=$('<div class="wiki-menu-li-1">'),
                    MapModuleTitle=$('<a href="javascript:;" class="menu-title">').text('世界地图').append('<span class="caret"></span>'),
                    MapModuleMenuUl2=$('<div class="wiki-menu-ul-2 " style="display: none;">'),
                    MapModuleMenuUl2_li2=$('<div class="wiki-menu-li-2">').append($('<a href="javascript:;" class="menu-title">').text('城镇').append('<span class="caret nav-rotate"></span>')),
                    MapModuleMenuUl3=$('<div class="wiki-menu-ul-3">');
                //遍历地图添加
                $('div[title="城镇"] a').each((i,e)=>{
                    let menu_Li=$('<div class="wiki-menu-li-3">').append($(e).clone().addClass('ment-title').text(e.textContent))
                    MapModuleMenuUl3.append(menu_Li);
                });
                MapModule.append(MapModuleTitle, MapModuleMenuUl2.append(MapModuleMenuUl2_li2.append(MapModuleMenuUl3)))
                $('.menu-wrap').prepend(MapModule)

                //树桩、宝箱添加标记框
                $('#TbPn-shuzhuang .wikitable tr:not(:first-child), #TbPn-baoxiang .wikitable tr:not(:first-child), #TbPn-sousuo .wikitable tr:not(:first-child)').each(function(i, e){
                    let td=$('<td>'),
                        boxPosition = $(this).find('td:nth-child(-n+2):not([rowspan])').text().trim().replace(/,/,',').replace(/[^\d,]/g,''), //获取树桩、宝箱坐标信息
                        checkBox = $('<input type="checkBox" title="标记物品已领取">').attr({id:`checkBox_${boxPosition}`}).on('click', {key: boxPosition, Rank: '资源'}, Bind.InputClick);
                    checkBox.prop('checked', GM_Config_Task?.['资源']?.[boxPosition]);
                    $(this).append(td.append(checkBox));
                });

                break;
        }

        /**
         * 通用功能
         */

        //首页不生效
        if(!webPath.includes('%E9%A6%96%E9%A1%B5')) {
            //遍历任务导航层级,获得最后一级导航
            let toclevel;
            for(let i=2;i>0;i--) {
                //console.log(i, `.toclevel-${i}`, document.querySelector(`.toclevel-${i}`));
                if(document.querySelector(`.toclevel-${i}`)) {
                    toclevel=`.toclevel-${i}`;
                    let taskTitleID=$(toclevel).find('a[href^="#"]').attr('href').replace('#','');
                    if($(`#${taskTitleID}`).parent().prop("tagName")==='H4') continue;
                    break;
                }
            }

            if(toclevel) {
                $(toclevel).each(function(i, e){ //遍历二级标题
                    let this_toc=this;

                    let taskTitleID=$(this).find('a[href^="#"]').attr('href').replace('#',''), //获得锚点作为ID
                        taskInputID=`checkTask_${taskTitleID}`, //使用任务锚点作为任务ID,避免出现同名任务
                        //获得任务ID,并过滤掉一些影响ID使用的特殊字符
                        taskTitleID_Selector=taskTitleID.replace(/([:.])/g,'\\$1');

                    let checkTask=$('<input type="checkbox" title="任务完成标记">').attr({id:taskInputID}).click(function(e, aa){
                        GM_Config_Task[taskTitleID]=this.checked;
                        GMAPI.save();
                        if(this.checked) {
                            $(this_toc).append('<span class="checkTask">√</span>');
                            headLineBox_ContentBox.show()
                        }
                        else {
                            $(this_toc).find('.checkTask').remove();
                            headLineBox_ContentBox.hide()
                        }

                    });

                    //插入任务完成标记Input
                    $(`#${taskTitleID_Selector}`).before(checkTask);

                    let label=$('<label>').attr({for:taskInputID}).text(taskTitleID);
                    $(`#${taskTitleID_Selector}`).parent().find('.mw-headline').html(label); //在标题前插入复选框

                    let headLineBox=$(`#${taskTitleID_Selector}`).parent(); //任务标题获得父容器

                    //创建内容容器
                    let headLineBox_ContentBox=$(`<div data-taskTitle="${taskTitleID}">`);
                    headLineBox_ContentBox.append(headLineBox.nextUntil('h2, h3')); //遍历获得父容器间的内容,并填充

                    headLineBox.click((e)=>{
                        headLineBox_ContentBox.toggle();
                    }); //为标题父容器添加折叠事件
                    label.click(()=>{
                        headLineBox_ContentBox.toggle();
                    });


                    headLineBox_ContentBox.insertAfter(headLineBox);
                    //读取任务状态
                    if(GM_Config_Task[taskTitleID]) {
                        checkTask.prop('checked', GM_Config_Task[taskTitleID]||false); //变更配置数据
                        $(this).append('√'); //添加任务状态
                        headLineBox_ContentBox.hide(); //隐藏掉任务内容
                    }
                });
            }
        }
    }

    // Your code here...
})();