Greasy Fork is available in English.

二定十线

二定十线,错八进六

// ==UserScript==
// @name         二定十线
// @namespace    http://tampermonkey.net/
// @version      0.7
// @description  二定十线,错八进六
// @author       You
// @include        http*://q1.88666333.com/*
// @grant   GM_xmlhttpRequest
// @grant   GM.getTab
// @grant   GM.saveTab
// @grant   GM.setValue
// @grant   GM.getValue
// @run-at document-body
// ==/UserScript==

(function() {
    'use strict';
    const LEN = 10;
    const MAX_TIMES = [1, 6, 6, 1, 6, 6, 6, 6, 6];
    const BET_AMOUNTS = [
        [1],
        [1, 2, 4, 8, 16, 32, 64, 128],
        [1, 2, 4, 8, 16, 32, 64, 128],
        [1],
        [1, 2, 4, 8, 16, 32, 64, 128],
        [1, 2, 4, 8, 16, 32, 64, 128],
        [1, 2, 4, 8, 16, 32, 64, 128],
        [1, 2, 4, 8, 16, 32, 64, 128],
        [1, 2, 4, 8, 16, 32, 64, 128],
    ]
    const SKIP_TIMES = 9;
    const PLACE_HOLDERS = ['abXXX', 'aXbXX', 'aXXbX', 'aXXXb', 'XabXX', 'XaXbX', 'XaXXb', 'XXabX', 'XXaXb', 'XXXab']
    const POOL1 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
               b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== combineNum) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== combineNum) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== combineNum) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== combineNum) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        }
        pools = pools.sort();
        return pools;
    };

    // 合双排除0, 合单排除9
    const POOL2 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
                b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 0) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 0) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 9) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 9) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        }
        pools = pools.sort();
        return pools;
    };

    // 合双排除8, 合单排除1
    const POOL3 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
                b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 8) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 8) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 1) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 1) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        }
        pools = pools.sort();
        return pools;
    };

    // 合双排除2, 合单排除7
    const POOL4 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
                b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 2) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 2) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 7) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 7) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        }
        pools = pools.sort();
        return pools;
    };
    // 合双排除6, 合单排除3
    const POOL5 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
                b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 6) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 6) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 3) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 3) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        }
        pools = pools.sort();
        return pools;
    };
    // 合双排除4, 合单排除5
    const POOL6 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
                b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 4) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 4) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    if ((a + b) % 10 !== 5) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    if ((a + b) % 10 !== 5) {
                        pools.push(holder.replace('a', a).replace('b', b));
                    }
                });
            });
        }
        pools = pools.sort();
        return pools;
    };
    // All
    const POOL7 = (index, resNums) => {
        let holder = PLACE_HOLDERS[index];
        let a, b;
        for (let i = 0; i < 5; i++) {
            if (holder[i] === 'a') {
                a = parseInt(resNums[i]);
            }
            if (holder[i] === 'b') {
                b = parseInt(resNums[i]);
            }
        }
        let combineNum = (a + b) % 10;
        let pools = [];
        if (combineNum % 2 === 0) {
            [1,3,5,7,9].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    pools.push(holder.replace('a', a).replace('b', b));
                });
            });
            [0,2,4,6,8].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    pools.push(holder.replace('a', a).replace('b', b));
                });
            });
        } else {
            [1,3,5,7,9].forEach(a => {
                [0,2,4,6,8].forEach(b => {
                    pools.push(holder.replace('a', a).replace('b', b));
                });
            });
            [0,2,4,6,8].forEach(a => {
                [1,3,5,7,9].forEach(b => {
                    pools.push(holder.replace('a', a).replace('b', b));
                });
            });
        }
        pools = pools.sort();
        return pools;
    };
    const POOLS = [POOL1, POOL1, POOL2, POOL2, POOL3, POOL4, POOL5, POOL6, POOL7];

    function signalA(index, gameResult) {
        if (gameResult.length < 1) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        return true;
    }

    function signalB(index, gameResult) {
        if (gameResult.length < 10) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL1(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }

    function signalC(index, gameResult) {
        if (gameResult.length < 10) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL2(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }
    // cor POOL3
    function signal3(index, gameResult) {
        if (gameResult.length < 10) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL3(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }
    // cor POOL4
    function signal4(index, gameResult) {
        if (gameResult.length < 10) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL4(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }
    // cor POOL5
    function signal5(index, gameResult) {
        if (gameResult.length < 10) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL5(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }
    // cor POOL6
    function signal6(index, gameResult) {
        if (gameResult.length < 10) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL6(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }
    // cor POOL7
    function signal7(index, gameResult) {
        if (gameResult.length < 4) {
            return false;
        }
        if ((gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) { // wait for previous result
            return false;
        }
        for (let i = 0; i < 8; i++) {
            if (POOL7(index, gameResult[i + 1][1]).includes(resToMask(gameResult[i][1])[index])) {
                return false;
            }
        }
        return true;
    }
    const SIGNALS = [signalA, signalB, signalC, signalA, signal3, signal4, signal5, signal6, signal7];
    var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
    function isPromise(obj) {
        return !!obj && ((typeof obj === 'object' && typeof obj.then === 'function') || (typeof obj === 'function' && typeof obj().then === 'function'));
    }
    /**
     * Wait Resource.
     *
     * @param {Function} resourceFn pred function to check resource
     * @param {Object} options
     * @returns Promise
     */
    function waitResource(resourceFn, options) {
        var optionsRes = Object.assign(
            {
                interval: 1000,
                max: 6
            },
            options
        );
        var current = 0;
        return new Promise((resolve, reject) => {
            var timer = setInterval(() => {
                if (isPromise(resourceFn)) {
                    resourceFn().then(res => {
                        if(res) {
                            clearInterval(timer);
                            resolve();
                        }
                    });
                } else if (resourceFn()) {
                    clearInterval(timer);
                    resolve();
                }
                current++;
                if (current >= optionsRes.max) {
                    clearInterval(timer);
                    reject('Time out');
                }
            }, optionsRes.interval);
        });
    }


    function requestAsync(data) {
        // console.log(data);
        return new Promise((resolve, reject) => {
            var reportAJAX_Error = (rspObj) => {
                console.error (`Request error: ${data}`);
                reject(`Request => Error ${data}  RES ${rspObj.status}!  ${rspObj.statusText}`);
            }

            var processJSON_Response = (rspObj) => {
                if (rspObj.status != 200 && rspObj.status != 304) {
                    reportAJAX_Error (rspObj);
                } else {
                    let resJSON = {};
                    try{
                        resJSON = JSON.parse(rspObj.responseText);
                    } catch(err) {
                        // ignore
                        console.log(err);
                    }
                    resolve(resJSON);
                }
            };
            GM_xmlhttpRequest ( {
                method:         "POST",
                url:            document.location.origin + "/!/MemberBet",
                headers: {
                    "Referer": document.location.href,
                    "Content-Type": "application/x-www-form-urlencoded"
                },
                data:           data,
                // responseType:   "json",
                onload:         processJSON_Response,
                onabort:        reportAJAX_Error,
                onerror:        reportAJAX_Error,
                ontimeout:      reportAJAX_Error
            });
        });
    }

        function ajaxAsync(method, url, data) {
         return new Promise((resolve, reject) => {
             $.ajax({
                 type: method,
                 url: url,
                 cache: false,
                 timeout: 1000 * 30,
                 dataType: 'json',
                 data: data,
                 success: function (msg) {
                     if (!msg || msg.error) {
                         reject(`Request ${url} => Error ${msg.error}`);
                     } else {
                         resolve(msg);
                     }
                 },
                 error: function () {
                     reject(`Fail to request ${url} with data ${data}`);
                 }
             });
         });
    }

    async function requestGameResult(gameDate) {
        return await ajaxAsync('get', '/!/GameListDate', {
            GameType: GameType,
            GameDate: gameDate,
            PageSize: 20,
            PageIndex: 0
        });
    }

    function parseResult(gameResult) {
        console.log(gameResult);
        if (!gameResult || !gameResult.List) {
            return null;
        }
        let res = [];
        gameResult.List.forEach(a => {
            if (a.Result) {
                res.push([a.Code, a.Result]);
            }
        });
        return res;
    }

    function resToMask(res) {
        return PLACE_HOLDERS.map(a => {
            let mask = 'XXXXX'.split('');
            for(let i = 0; i < 5; i++) {
                if (a[i] !== 'X') {
                    mask[i] = res[i];
                }
            }
            return mask.join('');
        });
    }

    async function bet(pools, amount) {
        let count = pools.length;
        pools = pools.map(a => `${a}%3D${amount}`);
        //const REQ_DATA = `SourceType=quick-comb&SourceData=%7B%22bet-type%22%3A%22d3%22%2C%22bet-count%22%3A${count}%2C%22dingwei-include%22%3A1%2C%22dingwei-1%22%3A%2212%22%2C%22dingwei-2%22%3A%221%22%2C%22dingwei-3%22%3A%221%22%2C%22hefeng-include%22%3A1%2C%22dan-include%22%3A1%2C%22shuang-include%22%3A1%7D&Game=${GameType}&Pools=${pools.join('%2C')}&Amount=${amount}`;
        const REQ_DATA = `SourceType=txt-import&SourceData=${count}+%E4%B8%AA%E5%8F%B7%E7%A0%81%EF%BC%88%E5%B8%A6%E9%87%91%E9%A2%9D%EF%BC%89&Game=${GameType}&Pools=${pools.join('%2C')}&Amount=`;
        console.log(REQ_DATA);
        return await requestAsync(REQ_DATA);
    }

    function addUI() {
        let div=document.createElement("div");
        div.setAttribute("style", "width:360px");
        let btn=document.createElement("BUTTON");
        btn.setAttribute("id", "betBtn");
        div.appendChild(btn);
        let select = document.createElement("SELECT");
        select.setAttribute("id", "strategy");
        select.innerHTML = "<option value =0>不翻倍</option><option value =1>错八进六</option><option value =2>错八进六(0 9)</option><option value =3>不翻倍(0 9)</option><option value =4>错八进六(1 8)</option>";
        select.innerHTML += "<option value =5>错八进六(2 7)</option><option value =6>错八进六(3 6)</option><option value =7>错八进六(4 5)</option><option value =8>错八进六(全)</option>"
        div.appendChild(select);
        let amount = document.createElement("INPUT");
        amount.setAttribute("id", "betAmount");
        amount.setAttribute("placeholder", "金额");
        amount.setAttribute("type", "text");
        div.appendChild(amount);
        let node = document.querySelector('#branch-info');
        let parentNode = node.parentNode;
        parentNode.insertBefore(div, node);
    }

    async function main() {
        if (window !== top) {
            console.log("NOT THE TOP");
            return;
        }
        console.log("START...", new Date());
        if (window.location.pathname === "/") { // login
            let user = await GM.getTab();
            console.log("DEBUG ", user);
            if (!!user && !!user.name) {
                await wait(1000);
                document.querySelector('#login-id').value = user.name;
                await wait(500);
                document.querySelector('#password').value = user.password;
                await wait(500);
                document.querySelector('.btn-primary').click();
            } else {
                document.querySelector('.btn-primary').onclick = async () => {
                    user.name = document.querySelector('#login-id').value;
                    user.password = document.querySelector('#password').value;
                    await GM.saveTab(user);
                }
            }
            return;
        }
        if (window.location.pathname === "/agreement.html") {
            await wait(500);
            document.querySelector('#lnk-agree').click();
            return;
        }
        await waitResource(async () => {
            console.log(document.querySelector('#account'));
            return typeof ENV  !== "undefined" && !!ENV[GameType] && !!ENV[GameType].Resulted && !!document.querySelector('#branch-info');
        });

        addUI();
        while (true) {
            let tabObj = await GM.getTab();
            // console.log('tabObj: ', tabObj);
            if (tabObj.started) {
                if (tabObj.gameType !== GameType) {
                    document.querySelector(`#game-type-${tabObj.gameType}`).click();
                }
                let lenInfo = tabObj.betInfos ? tabObj.betInfos.map(a => a.length).join(',') : '';
                document.querySelector('#betBtn').innerText = `结束(${lenInfo})`;
                document.querySelector("#strategy").selectedIndex = tabObj.selectedIndex;
                document.querySelector("#betAmount").value = tabObj.amount;
                document.querySelector('#betBtn').onclick = async () => {
                    tabObj.started = false;
                    tabObj.betInfos = null;
                    await GM.saveTab(tabObj);
                    document.querySelector('#betBtn').innerText = "...";
                }
            } else {
                document.querySelector('#betBtn').innerText = "开始";
                document.querySelector('#betBtn').onclick = async () => {
                    tabObj.started = true;
                    tabObj.selectedIndex = document.querySelector("#strategy").selectedIndex;
                    if (tabObj.selectedIndex < POOLS.length) {
                        tabObj.amount = parseFloat(document.querySelector("#betAmount").value).toFixed(1) || 0.1;
                        tabObj.betInfos = Array(LEN).fill([]);
                    } else {
                        tabObj.amount = parseFloat(document.querySelector("#betAmount").value).toFixed(0) || 1;
                        tabObj.betInfos = [[]];
                    }
                    tabObj.gameType = GameType;
                    tabObj.gameResult = [];
                    tabObj.lastGameID = 0;
                    await GM.saveTab(tabObj);
                    document.querySelector('#betBtn').innerText = "...";
                }
            }

            // 卡住了
            if (tabObj.started && new Date().getTime() / 1000 > (ENV[GameType].Current.End + 60)) {
                throw('卡住了');
            }
            if (!tabObj.started || new Date().getTime() / 1000 > ENV[GameType].Current.Close) {
                await wait(1000);
                continue;
            }

            // update game Result
            if (!tabObj.gameResult || tabObj.gameResult < 15 || ENV[GameType].Resulted[0][0] > tabObj.gameResult[0][0]) {
                let gameResult = parseResult(await requestGameResult(new Date().formatDate()));
                if (gameResult.length < 15) {
                    let preDateStr = new Date((new Date() - 1000 * 3600 * 24)).formatDate();
                    gameResult = gameResult.concat(parseResult(await requestGameResult(preDateStr)));
                    gameResult = gameResult.slice(0, 30);
                }
                tabObj.gameResult = gameResult;
                console.log("game result", gameResult);
                await GM.saveTab(tabObj);
            }
            // end update game result

            // 最后100 秒, 上次结果还没更新
            if (((tabObj.gameResult[0][0] + 1) % 10 !== ENV[GameType].Current.Code % 10) && new Date().getTime() / 1000  + 100 > ENV[GameType].Current.Close) {
                throw('开奖结果没更新');
            }

            // work
            if (tabObj.selectedIndex < POOLS.length) {
                for (let i = 0; i < LEN; i++) {
                    if (!!tabObj.betInfos[i] && tabObj.betInfos[i].length === 0) { // 初始下单
                        if (SIGNALS[tabObj.selectedIndex](i, tabObj.gameResult)) {
                            let pool = POOLS[tabObj.selectedIndex](i, tabObj.gameResult[0][1]);
                            let betAmount = tabObj.amount * BET_AMOUNTS[tabObj.selectedIndex][0];
                            if (betAmount !== 0) {
                                let res = await bet(pool, betAmount);
                                if (res.Error && res.Error !== '额度不足' && res.Error !== '账号已停用下注') {
                                    throw(res);
                                }
                                console.log(res);
                            }
                            tabObj.betInfos[i] = [ENV[GameType].Current.Code];
                            await GM.saveTab(tabObj);
                            continue;
                        }
                    }

                    if (!!tabObj.betInfos[i] && tabObj.betInfos[i].length > 0) { // 加码
                        let resultedLen = tabObj.gameResult.length;// ENV[GameType].Resulted.length;
                        if (tabObj.betInfos[i][tabObj.betInfos[i].length - 1] < tabObj.gameResult[resultedLen - 1][0]) {  // N期不下,重新开始
                            tabObj.betInfos[i] = [];
                            await GM.saveTab(tabObj);
                            continue;
                        }
                        let resIdx = -1; // 防止跳期
                        for (let idx = resultedLen - 1; idx >= 0; idx--) {
                            if (tabObj.betInfos[i][tabObj.betInfos[i].length - 1] === tabObj.gameResult[idx][0]) {
                                resIdx = idx;
                                break;
                            }
                        }
                        if (resIdx !== -1) { // 开奖
                            let pool = POOLS[tabObj.selectedIndex](i, tabObj.gameResult[resIdx + 1][1]);
                            let betRes = tabObj.gameResult[resIdx][1];
                            let betMaskRes = resToMask(betRes)[i];
                            console.log("开奖结果:", i, betMaskRes, `resIdx:${resIdx}`);
                            if (pool.includes(betMaskRes)) { // 中奖
                                console.log("中奖", i, betRes);
                                tabObj.betInfos[i] = [];
                                await GM.saveTab(tabObj);
                            } else { // 不中奖
                                if (tabObj.betInfos[i].length < MAX_TIMES[tabObj.selectedIndex]) { // 加码
                                    let betAmount = tabObj.amount * BET_AMOUNTS[tabObj.selectedIndex][tabObj.betInfos[i].length];
                                    if (betAmount !== 0) {
                                        let pool = POOLS[tabObj.selectedIndex](i, tabObj.gameResult[0][1]);
                                        let res = await bet(pool, betAmount);
                                        if (res.Error && res.Error !== '额度不足' && res.Error !== '账号已停用下注') {
                                            throw(res);
                                        }
                                    }
                                    tabObj.betInfos[i].push(ENV[GameType].Current.Code);
                                    await GM.saveTab(tabObj);
                                } else {
                                    // tabObj.started = false;
                                    tabObj.betInfos[i] = [];
                                    await GM.saveTab(tabObj); // 超出,重新开始
                                }
                            }
                        }
                    }
                }
            }
            // end work
            await wait(1000);
        }
    }
    main()
        .then(() => console.log("Main Done"))
        .catch((err) => {
        console.error(err, "Restart in 6 secs ...");
        setTimeout(() => location.reload(), 6 * 1000);
    });
})();