MyKirito Auto Action

自動點擊行動與PVP;使用腳本有風險,小心被茅場大大抓

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         MyKirito Auto Action
// @namespace    https://github.com/JCxYIS/mykirito_autoscript
// @version      3.1
// @description  自動點擊行動與PVP;使用腳本有風險,小心被茅場大大抓
// @author       JCxYIS
// @match        https://mykirito.com/*
// @grant        none
// ==/UserScript==

(function()
{
    'use strict';


    // 參數
    /** haha8 */
    const ACTION_NAME_LIST = ["狩獵兔肉", "自主訓練", "外出野餐", "汁妹", "做善事", "坐下休息", "釣魚"];
    const AWARD_NAME_LIST = ["修行1小時","修行2小時","修行4小時","修行8小時","領取獎勵"];
    const BOSS_NAME_LIST = ["挑戰"];
    const BATTLE_NAME_LIST = ["友好切磋", "認真對決", "決一死戰", "我要超渡你"];

    const BUTTON_AVAILABLE_CLASSNAME = "sc-AxgMl llLWDd";
    const BUTTON_DISABLED_CLASSNAME = "sc-AxgMl kPlkaT";
    const H3_CLASSNAME = "sc-fznyAO CWQMf";
    const CONTAINER_CLASSNAME = "sc-fzokOt hLgJkJ";
    const BATTLE_CONTAINER_CLASSNAME = "sc-fzplWN hRBsWH";
    const INJECTION_CLASSNAME = "sc-fzplWN hRBsWH";


    // class
    class RecursiveAction
    {
        constructor(butt, clicktimes)
        {
            this.butt = butt
            this.clicktimes = clicktimes
            this.hasClicked = 0
        }
    }

    // 變數
    /** 要做出的行動 是 RecursiveAction 的 List*/
    var actionList = [];

    /** 樓層獎勵按鈕 */
    var floorAwardButt;

    /** 所有我們建立的遞迴按鈕 */
    var myFunctionButtons = [];

    /** 注入網頁的元素  */
    var text_title;
    var text_subtitle1;
    var text_subtitle2;
    var text_subtitle3;
    var text_loopInputInfo;
    var input_loopInput;
    var butt_start;
    var butt_stop;
    var butt_removelast;
    var butt_shuffle;
    var checkbox_autoFloorReward;


    // 進入點
    setInterval ( function ()
        {
            if ( this.lastPath != location.pathname )
            {
                this.lastPath = location.pathname;
                console.log("SWITCH!:"+location.pathname);
                EndREALRecursive();
                main ();
            }
        }
        , 1000
    );


    // 主函式
    function main()
    {
        // 先決定我們在哪個頁面
        /** */
        let usingActionList = [];
        /** 要插入功能表的地方*/
        let usingInjectionPos;
        /** 要插入功能表的地方的順位 */
        let usingInjectionOrder;

        if(location.pathname == "/") // 跟目錄
        {
            usingActionList = ACTION_NAME_LIST.concat(AWARD_NAME_LIST);
            usingInjectionPos = document.getElementsByClassName(BATTLE_CONTAINER_CLASSNAME)[0].parentNode;
            usingInjectionOrder = 4;
        }
        else if (location.pathname.startsWith("/profile/")) // 準備戰鬥
        {
            usingActionList = BATTLE_NAME_LIST;
            usingInjectionPos = document.getElementsByClassName(BATTLE_CONTAINER_CLASSNAME)[0].parentNode;
            usingInjectionOrder = 2;
        }
        else if (location.pathname.startsWith("/boss"))
        {
            usingActionList = BOSS_NAME_LIST;
            usingInjectionPos = document.getElementsByClassName(BATTLE_CONTAINER_CLASSNAME)[0].parentNode;
            usingInjectionOrder = 1;
        }
        else
        {
            // 不是可以自動的地方就滾
            return;
        }


        // 拿到可點的按紐們
        /** 所有按鈕,包含不被遞迴的 */
        let allbuttons = document.getElementsByTagName('button');
        /** 所有被我們標示可遞迴的按鈕 */
        let actionButtons = [];
        floorAwardButt = undefined;
        console.log(usingActionList);
        for(let i = 0; i < allbuttons.length; i++)
        {
            if(allbuttons[i].offsetParent !== null) /*.parentElement.style.display != "none"*/
            {
                for(let j = 0; j < usingActionList.length; j++)
                {
                    if(allbuttons[i].innerText == usingActionList[j])
                    {
                        actionButtons.push(allbuttons[i]);
                        // console.log(allbuttons[i]);
                        continue;
                    }
                }

                if(allbuttons[i].innerText == "領取獎勵")
                {
                    floorAwardButt = allbuttons[i];
                    console.log(allbuttons[i]);
                    continue;
                }
            }
        }

        // 製作選單
        /** 要注入的主東西 */
        var inject             = document.createElement('div');
        usingInjectionPos.insertBefore(inject, usingInjectionPos.childNodes[usingInjectionOrder])//.appendChild(inject);

        /** 注入的元素 */
        text_title         = document.createElement("h3");
        text_subtitle1     = document.createElement('p');
        text_subtitle2     = document.createElement('p');
        text_subtitle3     = document.createElement('p');
        text_loopInputInfo = document.createElement('span');
        input_loopInput    = document.createElement('input');

        inject.classList = INJECTION_CLASSNAME;
        inject.style.backgroundColor = "#2868B011"

        text_title.classList = H3_CLASSNAME;
        text_title.innerHTML = "自律行動";
        text_subtitle1.innerHTML = "大家都應該去玩 <a href='https://pmotschmann.github.io/Evolve/' target='_blank'>進化 Evolve</a>";
        text_subtitle2.innerHTML =
            "<a href='https://greasyfork.org/zh-TW/scripts/413368-mykirito-auto-action' target='_blank'>腳本網址</a> | " +
            "<a href='https://github.com/JCxYIS/mykirito_autoscript' target='_blank'>腳本原始碼</a> | " +
            "<a href='https://tinyl.io/mykiritowiki' target='_blank'>攻略網</a>";
        text_subtitle3.innerHTML = "";

        //loopInput.classList = "sc-AxheI fniENO";
        text_loopInputInfo.innerHTML = "連續點擊數:";
        input_loopInput.type = "number";
        input_loopInput.min = 1;
        input_loopInput.max = 48763;
        input_loopInput.step = 1;
        input_loopInput.value = 1;


        // 新增剛綁好的按鈕
        myFunctionButtons = [];
        for(let i = 0; i < actionButtons.length; i++)
        {
            //console.log("按鈕名稱:"+buttons[i].innerHTML);
            let newButt = document.createElement('button');
            newButt.classList = BUTTON_AVAILABLE_CLASSNAME;
            newButt.innerHTML = ""+actionButtons[i].innerHTML;
            newButt.onclick = ()=>{ AddAction( actionButtons[i] ); }
            myFunctionButtons.push(newButt);
        }

        // remove last
        butt_removelast = document.createElement('button');
        butt_removelast.innerHTML = "刪除最後";
        butt_removelast.classList = BUTTON_AVAILABLE_CLASSNAME;
        butt_removelast.onclick = ()=>{ RemoveLastAction(); }

        // random
        butt_shuffle = document.createElement('button');
        butt_shuffle.innerHTML = "隨機排列";
        butt_shuffle.classList = BUTTON_AVAILABLE_CLASSNAME;
        butt_shuffle.onclick = ()=>{ ShuffleAction(); }


        // 往,吾往也
        butt_start = document.createElement('button');
        butt_start.innerHTML = "開始";
        butt_start.classList = BUTTON_AVAILABLE_CLASSNAME;
        butt_start.onclick = ()=>{ StartREALRecursive(); }

        // 止,吾止也
        butt_stop = document.createElement('button');
        butt_stop.innerHTML = "停止/清除";
        butt_stop.classList = BUTTON_AVAILABLE_CLASSNAME;
        butt_stop.onclick = ()=>{ EndREALRecursive(); }

        // 自動樓層
        checkbox_autoFloorReward = document.createElement("input");
        checkbox_autoFloorReward.type = "checkbox";
        checkbox_autoFloorReward.id = "checkbox_autoFloorReward";
        let checkbox_autoFloorReward_label = document.createElement("label");
        checkbox_autoFloorReward_label.htmlFor = "checkbox_autoFloorReward";
        checkbox_autoFloorReward_label.innerHTML = "自動領取樓層獎勵";
        // checkbox_autoFloorReward.classList = BUTTON_AVAILABLE_CLASSNAME;


        // 把所有東西渲染上網頁!
        inject.appendChild(text_title);
        inject.appendChild(text_subtitle1);
        inject.appendChild(text_subtitle2);
        for(let i = 0; i < myFunctionButtons.length; i++)
        {
            inject.appendChild(myFunctionButtons[i]);
        }
        inject.appendChild(document.createElement('br'));
        inject.appendChild(text_loopInputInfo);
        inject.appendChild(input_loopInput);
        inject.appendChild(document.createElement('br'));
        inject.appendChild(butt_shuffle);
        inject.appendChild(butt_removelast);
        inject.appendChild(document.createElement('br'));
        if(floorAwardButt) {
            inject.appendChild(checkbox_autoFloorReward);
            inject.appendChild(checkbox_autoFloorReward_label);
            inject.appendChild(document.createElement('br'));
        }
        inject.appendChild(butt_start);
        inject.appendChild(butt_stop);
        inject.appendChild(document.createElement('br'));
        inject.appendChild(text_subtitle3);


    } // end main



    // 以下是功能
    var recursiveTimerId;
    var clickCombo = 0;
    var clickComboTotal = 0;
    var continuousInvalidClick = 0;
    var isLastActionClick = false;

    function AddAction(butt)
    {
        let newAction = new RecursiveAction(butt, input_loopInput.value);
        actionList.push(newAction);
        console.log("加入action: "+butt.innerHTML+":要按"+input_loopInput.value+"次");
        PrintAction();
    }

    function RemoveLastAction()
    {
        // let newAction = new RecursiveAction(butt, input_loopInput.value);
        actionList.pop();
        console.log("刪除 action");
        PrintAction();
    }

    function ShuffleAction()
    {
        // https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
        var currentIndex = actionList.length, temporaryValue, randomIndex;

        // While there remain elements to shuffle...
        while (0 !== currentIndex)
        {
            // Pick a remaining element...
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;

            // And swap it with the current element.
            temporaryValue = actionList[currentIndex];
            actionList[currentIndex] = actionList[randomIndex];
            actionList[randomIndex] = temporaryValue;
        }

        console.log("shuffle action");
        PrintAction();
    }

    function PrintAction()
    {
        let str = "<b>行動清單:</b><br>";
        actionList.forEach(element => {
            let addstr = ""+element.butt.innerHTML+" "+element.clicktimes+" 次";

            if(element.hasClicked == element.clicktimes)
            {
                addstr = "<span style='color:green'>"+addstr+":"+element.hasClicked+" "+"</span><br>";
            }
            else if(element.hasClicked != 0)
            {
                addstr = "<span style='color:orange'>"+addstr+":"+element.hasClicked+" "+"</span><br>";
            }
            else
            {
                addstr = ""+addstr+":"+element.hasClicked+" "+"<br>";
            }

            str += addstr;
        });

        if(text_subtitle3)
            text_subtitle3.innerHTML = str;
    }

    function StartREALRecursive()
    {
        // EndRecursive();
        for(var i = 0; i < myFunctionButtons.length; i++)
        {
            myFunctionButtons[i].classList = BUTTON_DISABLED_CLASSNAME;
        }
        butt_start.classList = BUTTON_DISABLED_CLASSNAME;
        butt_shuffle.classList = BUTTON_DISABLED_CLASSNAME;
        butt_removelast.classList = BUTTON_DISABLED_CLASSNAME;
        checkbox_autoFloorReward.disabled = true;

        if(recursiveTimerId)
        {
            console.warn("已經開始過了!");
        }
        else
        {
            REALRecursive();
            console.log("讓我們開始吧!");
        }
    }



    function REALRecursive()
    {
        // TODO
        /** Random: 20~50秒檢查一次 */
        let nextTime = 20000+Math.random()*30000;

        /**本次行動的目標 */
        let action = null;
        for(let i = 0; i < actionList.length; i++)
        {
            if(actionList[i].hasClicked < actionList[i].clicktimes)
            {
                action = actionList[i];
                break;
            }
        }
        if(action == null)
        {
            text_subtitle2.innerHTML = "<span style='color:green'>自律行動執行完成!</span>";
            return;
        }

        /**本次行動的目標按鈕 */
        let butt = action.butt;


        // start!
        if(butt.disabled || butt.classList == BUTTON_DISABLED_CLASSNAME)
        {
            // 仍在鎖,不能按
            isLastActionClick = false;
            continuousInvalidClick = 0;
            //console.log("按鈕不能按! 下次檢查時間(n秒後):"+nextTime/1000);

            // 那去檢查樓層獎勵吧
            if(checkbox_autoFloorReward.checked && floorAwardButt && !floorAwardButt.disabled)
            {
                floorAwardButt.click();
                console.log("按樓層獎勵");
            }
        }
        else
        {
            // 按下去!
            butt.click();
            clickCombo++;
            clickComboTotal++;
            action.hasClicked += 1;

            if(isLastActionClick)
            {
                continuousInvalidClick++;
            }
            isLastActionClick = true;
            //console.log(clickCombo+"("+clickComboTotal+") combo!! "+butt.innerHTML + "\n下次檢查時間(n秒後):"+nextTime/1000);
            //console.log(butt);
        }

        if(continuousInvalidClick >= 5)
        {
            text_subtitle2.innerHTML = "<span style='color:yellow'>無效點擊達 5 次。請重新執行!</span>";
            return;
        }
        else
        {
            text_subtitle2.innerHTML = "<span style='color:cyan'>自律行動執行中!</span>";
            if(continuousInvalidClick > 0)
            {
                text_subtitle2.innerHTML += "<br><span style='color:yellow'>連續點擊次數( 5 次將會暫停腳本):"+continuousInvalidClick+" / 5";
            }
            recursiveTimerId = setTimeout( ()=>{REALRecursive()} , nextTime);
        }

        PrintAction();
        //text_subtitle2.innerHTML += "點擊【"+butt.innerHTML+"】,已點擊了 "+clickCombo+" ("+clickComboTotal+") 次!";
    }
    function EndREALRecursive()
    {
        window.clearTimeout(recursiveTimerId);
        recursiveTimerId = null;

        clickCombo = 0;
        continuousInvalidClick = 0;
        isLastActionClick = false;

        actionList = []
        PrintAction();

        for(var i = 0; i < myFunctionButtons.length; i++)
        {
            myFunctionButtons[i].classList = BUTTON_AVAILABLE_CLASSNAME;
        }

        if(butt_start)
        {
            butt_start.classList = BUTTON_AVAILABLE_CLASSNAME;
            butt_shuffle.classList = BUTTON_AVAILABLE_CLASSNAME;
            butt_removelast.classList = BUTTON_AVAILABLE_CLASSNAME;
            checkbox_autoFloorReward.disabled = false;
        }

        if(text_subtitle2)
            text_subtitle2.innerHTML = "謝謝您的惠顧,敬祝您健康愉快,萬事如意,再見。";
        console.log("停止遞迴;清除參數。");
    }
}
)();