evlon / 移人家积分PK游戏助手(云端同步)

// ==UserScript==
// @name         移人家积分PK游戏助手(云端同步)
// @copyright 2018, evlon (https://openuserjs.org/users/evlon)
// @version      0.8.1
// @description  用于辅助进行PK答题
// @license MIT
// @author       evlon
// @include     /^https?://(?:api\.yiqiapp\.cn(:\d+)?\/dkdt(web)?\/)/
// @grant        none
// ==/UserScript==
//http://api.yiqiapp.cn/dkdtweb/answer
(function() {
    'use strict';
    var syncMessager = null;
    var targetWindow = null;
    function SyncMessageClient(win,domain){
        var funName = 0;
        var scope = {};
        function getNextCallbackName(callback){
            var retfunc = "cb_" + (funName++);
            scope[retfunc] = function(){
                callback.apply(win,arguments);
            };

            return retfunc;
        }

        window.addEventListener("message",function(ev){
            try{
            var rdata = JSON.parse(ev.data);
            var fn = scope[rdata.fn];
            fn.apply(win,rdata.args);
            delete scope[rdata.fn];
            }
            catch(e){}
        });

        this.sendMessage = function(targetWindow,data,callback,targetDomain){
            var callData = {data:data,fn:getNextCallbackName(callback)};
            targetWindow.postMessage(JSON.stringify(callData),targetDomain || "*");
        };
    }

    function SyncMessageServer(win,domain,onSendMessage){
        window.addEventListener("message",function(ev){
            try{
            var json = JSON.parse(ev.data);
            var fn = json.fn;
            console.dir(json);
            var result = onSendMessage(ev);
            ev.source.postMessage(
                JSON.stringify({fn:fn,args:[result]}),"*");
            }
            catch(e){}
        });
    };
    function queryAnswserByQuestion(q,fn) {

        syncMessager.sendMessage(targetWindow,{cmd:"query",q:q},function(a){
            fn(a);
        },"*");
    };

    function saveAnswser(q, a) {
        q = q.replace(/\d\:/,'');
        syncMessager.sendMessage(targetWindow, { cmd: "save", q: q ,a:a}, function (ok) {}, "*");
    }
    function getScoreLeft(){
        var leftEle = document.getElementById('number_left');
        if(leftEle){
            return parseFloat(leftEle.innerText);
        }
    }

    function getScoreRight(){
        var rightEle = document.getElementById('number_right');
        if(rightEle){
            return parseFloat(rightEle.innerText);
        }
    }
    function IsWillFullMark(){
        return getScoreLeft() >= 800 && getScoreRight() <= 400;
    }

    function beginFindAndAutoAnswer(a){
        var timerId = 0;
        var live = 10;
        function autoAnswer(){
            document.querySelectorAll('div.answer').forEach((n,i)=>{
                var text = n.innerText;
                if(text.replace(/(\s|\t)+/g, '').indexOf(a) != -1)
                {
                    live = 0;
                    var sleep = IsWillFullMark()?2000:700;
                    var nodeAnswer = n;
                    setTimeout(function(){
                        try{
                            nodeAnswer.click();
                        }
                        catch(e){
                            console.log('自动回答错误,手动回答吧');
                        }
                    },sleep);
                }
            });
            if(live-- > 0)
            {
                timerId = window.setTimeout(autoAnswer,500);
                console.log('find answer ...');
            }
        }
        timerId = window.setTimeout(autoAnswer,500);
    }
    window.saveQ = saveAnswser;
    window.queryQ = queryAnswserByQuestion;

    function initSystem(){
        if(syncMessager == null){
            syncMessager = new SyncMessageClient(window,"*");
        }
        if(targetWindow == null){
            var iframe = document.createElement("iframe");
            iframe.id = "localStorageDatabase";
            iframe.src = "http://hub.qtcn.tech:85/localStorage.html";
            iframe.style = "width:0px;height:0px";
            document.body.appendChild(iframe);
            targetWindow = document.getElementById("localStorageDatabase").contentWindow;
        }
    }

    function init_hook() {
        if (location.href.match(/dkdt(web)?\/answer/) && window.myWs && window.myWs.onmessage && window.myWs.__hooked__ != true) {
            var currentQuestion = {
                q: null,
                done: false
            };

            var _emit = window.myWs.onmessage;

            function hookEmit(t) {
                console.dir(t);
                var objThis = window.myWs;
                var args = Array.prototype.slice.apply(arguments);
                try{
                    var data = JSON.parse(t.data);

                    if ("Question" == data.type || "question" == data.type) {
                        console.log('hook:Question');
                        currentQuestion.q = data;

                        console.log("currentQuestion.q");
                        console.dir(currentQuestion.q);
                        var q = data.questionTitleStr;
                        queryAnswserByQuestion(q,function(a){
                            if (a) {
                                var index = 1;
                                data.questionOptionsArray.forEach((n,idx)=>{
                                    if (n.optionContentStr.replace(/(\s|\t)+/g, '') == a) {
                                        n.optionContentStr = "* " + n.optionContentStr + " *";
                                        index = idx + 1;
                                    }
                                });
                                data.questionTitleStr = index.toString() + ':' + data.questionTitleStr;
                                console.log('found answer:' + index + ':' + a);
                                var newEvent = new MessageEvent(t.type || "message",{data:JSON.stringify(data),origin:t.origin,srcElement:t.srcElement,target:t.target});
                                args[0] = newEvent;
                                beginFindAndAutoAnswer(a);
                                //t.data = JSON.stringify(data);
                                // hook new questtion
                            }
                            return _emit.apply(objThis, args);
                        });
                        return;
                        /*
                    var a = queryAnswserByQuestion(q);
                    if (a) {
                        data.questionOptionsArray.forEach(n=>{
                            if (n.optionContentStr == a) {
                                n.optionContentStr = "* " + n.optionContentStr + " *";
                            }
                        }
                        );
                        args[0] = JSON.stringify(t);
                        // hook new questtion
                    }
                    */

                    } else if (data.type == 'answer_complete') {
                        console.log('hook:answer_complete');
                        console.dir(data);

                        var a = null;
                        if (currentQuestion.q) {
                            currentQuestion.q.questionOptionsArray.forEach(n=>{
                                if (n.id == data.rightAnswer) {
                                    a = n.optionContentStr.replace(/(^\*\s+)|(\s+\*$)/g, '');
                                }
                            }
                                                                          );

                            saveAnswser(currentQuestion.q.questionTitleStr, a);

                        }

                    }}
                catch(e){
                    console.log(e);
                }
                return _emit.apply(objThis, args);
            }
            hookEmit.__hooked__ = true;

            if (_emit && _emit.__hooked__!= true) {

                window.myWs.onmessage = hookEmit;
                console.log('hooked onmessage');
                console.log(window.myWs.onmessage);
            }

            localStorage.setItem('myGames', 20);
            setTimeout(init_hook, 50);

        } else {
            console.log('try hook ....');
            setTimeout(init_hook, 50);
        }

    }
    initSystem();
    init_hook();
}
)();