route assistant

金书红颜录路线武功规划脚本,需配合相关文本内容使用

Versão de: 08/11/2015. Veja: a última versão.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name        route assistant
// @namespace   myhead
// @description 金书红颜录路线武功规划脚本,需配合相关文本内容使用
// @version     1
// @grant       none
// @include     
// ==/UserScript==
/*
    oResult={
        '拳':[aRegExpSearchResult1{[0](matched content),[1](captured content in parenthesis),[2],index,input},aRegExpSearchResult2...],
        '剑':[],
        '兵':[],
        '特':[],
        '暗':[],
        '内':[],
        '轻':[],
        '余':[]   
    }
    Pos= aC1[i] ={
            __Con: {
                sName: route position name,
                sCon: RegExp context of the position,
                nStart: start index in sCon,
                nEnd: end index in sCon
            },
            next: []
            //next is deeper list of route option object
        }

*/

var aC1= [],
    //aC1 correspond to the list of route root object 
    aRoute=[],
    oResult={},
    sOrigin='',
    sResult='',
    t;
    
var mainDiv=document.createElement('div'),
    navi=document.createElement('div'),
    div1=document.createElement('div'),
    div2=document.createElement('div'),
    div2p=document.createElement('code'),
    div2f=document.createElement('div'),
    round=document.createElement('select'),
    speci=document.createElement('span'),
    toggle= document.createElement('button'),
    oTarget= {};
    
toggle.innerHTML="打开路线武功规划器"
toggle.onclick=function(){
    if(sOrigin== '') main();
    mainDiv.style.display='';
};
window.onload=function(){
    oTarget= document.getElementById('bodyContent');
    oTarget.insertBefore(toggle,oTarget.firstChild);
};

    
function main(){
    //search route and set UI;
    if(!oTarget){
        alert('找不到源数据');
        return;
    };
    sOrigin=oTarget.textContent;
    var rP1= /#(.+)/g;
    for(var i=0,aTemp;i<100;i++) {
        aTemp=rP1.exec(sOrigin);
        //aTemp contains [0] [1] .index .input
        if (aTemp== null) break;
        aC1[i]={
            //aC1[i] is route option object
            __Con: {
                sPath: aTemp[0],
                sName: aTemp[1],
                sCon: aTemp.input,
                nStart: aTemp.index,
                nEnd: undefined
            },
            next: []
            //next is deeper list of route option object
        };
        //initialise the route result array
        aRoute[i]= aC1[i];
        if(i>0) 
            aC1[i-1].__Con.nEnd= aTemp.index-1;
    };
    //create UI and set up initial option list
    mainDiv.setAttribute('style','position: absolute; left: 200px; top: 100px; width: 800px; height: 600px; background: white; border: solid #E0E0E0; overflow: auto;resize: both;');
    //
    navi.innerHTML=
        "<button onclick='div1.style.display=\"\";div2.style.display=\"none\";'>路线选择</button>"+
        "<button onclick='div2.style.display=\"\";div1.style.display=\"none\";'>武功统计</button>"+
        "<button onclick='mainDiv.style.display=\"none\";' style='float: right;'>隐藏</button>";
    navi.setAttribute('style','border-bottom: solid #F0F0F0; background: #F0F0F0');navi.setAttribute('style','border-bottom: solid #F0F0F0;background: #F0F0F0');
    div2.style.display='none';
    div2.innerHTML+= '请选择周目:';
    for(var i=1;i<7;i++)
        round.innerHTML+='<option value='+i+'>'+i+'周</option>';
    div2.appendChild(round);
    button= document.createElement('button');
    button.innerHTML='开始统计';
    button.onclick= analyse;
    div2.appendChild(button);
    //create filter option bar div2f
    div2f.innerHTML+= '结果过滤器:';
    speci.innerHTML+=
        '名称显示<select><option value=1 selected>简名</option><option value=2>全名</option></select> '+
        '类别<select><option value=0 selected>&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="拳">拳</option><option value="剑">剑</option><option value="兵">兵</option><option value="特">特</option><option value="暗">暗</option><option value="内">内</option><option value="轻">轻</option><option value="[^拳剑兵特暗内轻]">其他</option></select>'+
        '阴阳<select><option value=0 selected>&nbsp;&nbsp;&nbsp;&nbsp;</option><option value="阴">阴</option><option value="阳">阳</option></select>'+
        '最低数值<select><option value=0 selected>&nbsp;&nbsp;&nbsp;&nbsp;</option><option value=2 >2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option></select>';
    div2f.appendChild(speci);
    button= document.createElement('button');
    button.innerHTML='过滤结果';
    button.onclick=filter;
    div2f.appendChild(button);
    div2.appendChild(div2f);
    div2.appendChild(div2p);
    var tarList=document.createElement('ol');
    for(var i=0,li,doList;i<aC1.length;i++){
        //set up the root group
        li= document.createElement('li');
        li.innerHTML=aC1[i].__Con.sName;
        doList= dive(aC1[i],1);
        //set up the first layer option
        if(doList.length>0){
            var select=document.createElement('select');
            select.onchange=routeQuery;
            select.innerHTML+="<option value='"+i+"' selected ></option>"
            for(var j=0;j<doList.length;j++){
                //add drop-down list for each option
                select.innerHTML+=
                    "<option value='"+i+"."+j+"' >"+doList[j].__Con.sName+"</option>"
            };
            li.appendChild(select);
        };
        tarList.appendChild(li);
    };
    div1.innerHTML='<button onclick="checkBinding();">检查路线冲突</button>';
    div1.appendChild(tarList);
    mainDiv.appendChild(navi);
    mainDiv.appendChild(div1);
    mainDiv.appendChild(div2);
    document.body.appendChild(mainDiv);
}

function dive(Pos,nSym){
    //dive into route chain,group represents the number of option root
    var rP= new RegExp('\\s'+nSym+'(.*)','g'),
        sContext= Pos.__Con.sCon.substring(Pos.__Con.nStart,Pos.__Con.nEnd);
    for(var i=0,aTemp;i<100;i++) {
        aTemp= rP.exec(sContext);
        if(aTemp== null) break;
        Pos.next[i]={
            __Con: {
                sPath: Pos.__Con.sPath+'-'+aTemp[1],
                sName: aTemp[1],
                sCon: aTemp.input,
                nStart: aTemp.index,
                nEnd: undefined
            },
            next: []
        };
        if(i>0) Pos.next[i-1].__Con.nEnd= aTemp.index-1;
    }
    return Pos.next;
    //the newly matched route to create drop-down of
}

function sort(aEntry,aTarget){
    var i,nIndi;
    if(!aTarget[0]){
        aTarget[0]=aEntry;
        return;
    }
    if(!aEntry[1]) nIndi=0;
    else nIndi=parseInt(aEntry[1].match(/\d/)[0]);
    for(i=0;i<aTarget.length;i++){
        if(nIndi< aTarget[i][1]){
            for(var j=aTarget.length-1;j>= i;j--){
                aTarget[j+1]= aTarget[j];
            }
            break;
        }
    }
    aTarget[i]= aEntry;
}

//following fuctions are event handle

function routeQuery(){
    //connecting with selcet.onchange, the event handle to search option of drop-down list,whose value corresponds to the index of content array.Then create relevant drop-down list.
    while(this.nextSibling)
        this.parentNode.removeChild(this.nextSibling);
    if(this.value== this.firstChild.value) return;
    var aValue=this.value.match(/\d+/g),
        //[this] is the node elements triggering the event.[this.value] has form like'1.2.3'
        Pos=aC1[aValue[0]],
        //Pos is route option object
        nSym= 0;
        //nSym is the current route layer of Pos
    for(var i=1;i<aValue.length;i++){
        //convert string path in select's value to virtual array path
        Pos=Pos.next[aValue[i]];
        nSym++;
    };
    var list= dive(Pos,nSym+1);
    if (list.length>0) {
        var select=document.createElement('select');
        select.onchange=routeQuery;
        select.innerHTML+="<option value='"+this.value+"' selected ></option>";
        for(var j=0;j<list.length;j++){
            select.innerHTML+=
                "<option value='"+this.value+"."+j+"' >"+list[j].__Con.sName+"</option>";
        };
        this.parentNode.appendChild(select);
    }
    //if there is no sub option in deeper layer,log the result 
    aRoute[aValue[0]]= Pos;
}

//connect with the button '开始统计'
function analyse(){
    oResult={};
    for(var i=0,oT;i<aRoute.length;i++){
        var rP2=/\S+?(\+[1-9][阴阳]?)?(\-\S)?(\?[1-6])?(?=\s|$)/gm;
        oT=aRoute[i].__Con;
        sResult=oT.sCon.substring(oT.nStart,oT.nEnd);
        t=sResult.match(/@.*/);
        if(!t) continue;
        else sResult=t[0].substring(1);
        for(var j=0,aT=[];j<200;j++){
            aT=rP2.exec(sResult);
            //at[0]-- content; at[1]-- +[rank][yinyang]; at[2]-- -[type]; at[3]-- ?[round]
            if(!aT) break;
            if(aT[3] && parseInt(aT[3].substring(1))> round.value) continue;
            if(!aT[2]) aT[2]='未分类';
            else aT[2]=aT[2].substring(1);
            if(!oResult[aT[2]]) oResult[aT[2]]=[];
            sort(aT,oResult[aT[2]]);
        }
    }
    sResult='';
    //output
    for(var x in oResult){
        sResult+= '类别——'+x+':<br />&nbsp;&nbsp;';
        var rTp= /[^-?\s]+/;    
        for(var i=0;i<oResult[x].length;i++){
            sResult+= oResult[x][i][0]+'&nbsp;&nbsp;';
        };
        sResult+='<br /><br />';
    }
    div2p.innerHTML= sResult;
}

//connect with button in filter bar
function filter(){
    var aOut= speci.children,
        rTp= /[^-?\s]+/;
    sResult= '';
    //aOut[1]-- string representing type; aOut[2]-- string representing yin yang; aOut[3]-- number representing value rank
    for(var x in oResult){
        if(aOut[1].value!= '0'){
            var rP=new RegExp(aOut[1].value);
            if(!rP.test(x)) continue;
        }
        sResult+= '类别——'+x+':<br />&nbsp;&nbsp;';
        if(aOut[0].value== 1){
            for(var i= 0,aTemp;i<oResult[x].length;i++){
                aTemp=oResult[x][i];
                if(aOut[2].value!= '0')
                    if(aTemp[1])
                        if(t= aTemp[1].match(/[阴阳]/))
                            if(t[0]!= aOut[2].value)
                                continue;
                if(aOut[3].value== '0' || parseInt(aTemp[1].match(/\d/)[0])>= aOut[3].value)
                    sResult+= aTemp[0].match(rTp)[0]+'&nbsp;&nbsp;';
            };
        }
        else{
            for(var i= 0,aTemp;i<oResult[x].length;i++){
                aTemp=oResult[x][i];
                if(aOut[2].value!= '0')
                    if(aTemp[1])
                        if(!(new RegExp(aOut[2].value).test(aTemp[1])))
                            continue;
                if(aOut[3].value== '0' || parseInt(aTemp[1].match(/\d/)[0])> aOut[3].value)
                    sResult+= aTemp[0]+'&nbsp;&nbsp;';
            }
        }
        sResult+='<br /><br />';
    }
    div2p.innerHTML= sResult;
}

//connect with button to confirm proper binding
function checkBinding(){
    var aBind=[],Compare={},sCollision='';
    for(var i=0;i<aRoute.length;i++){
        t= aRoute[i];
        t=t.__Con;
        var aT= t.sPath.split(/-/);
        for(var j=0;j<aT.length;j++){
            Compare[aT[j].match(/[^ ]+/)[0]]= 1;
        };
        var rP= /[^ \-\n]*bind\s*([^ \-\n]+)/g;
        for(var j=0,aT1;j<100;j++){
            aT1= rP.exec(t.sPath);
            if(aT1) aBind.push(aT1);
            else break;
        }
    }
    for(var i=0,aT;i<aBind.length;i++){
        if(!Compare[aBind[i][1]]) sCollision+= aBind[i].input+"\n";
    }
    if(sCollision!= '')
        alert ('路线冲突:\n'+sCollision.replace(/bind/g,'绑定'));
    else 
        alert ('无冲突');
}