Greasy Fork

Greasy Fork is available in English.

华为商城抢购助手

同步华为商城服务器时间,毫秒级华为商城抢购助手

当前为 2020-03-17 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         华为商城抢购助手
// @namespace    https://github.com/gorkys/TampermonkeyHub
// @version      1.2.0
// @description  同步华为商城服务器时间,毫秒级华为商城抢购助手
// @author       Gorkys
// @license      MIT

// @match        https://www.vmall.com/product/*.html
// @match        https://*.cloud.huawei.com/*
// @match        https://www.vmall.com/product/*.html?*
// @match        https://www.vmall.com/order/nowConfirmcart
// @match        https://sale.vmall.com/rush/*
// @supportURL   https://github.com/gorkys/TampermonkeyHub/issues
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function() {
    'use strict';

    let STARTTIME = 0 // 活动开始时间
    let OFFSETTIME = 0 // 与本地时间相差
    let NETWORKTIME = 0 // 网络延迟

    window.onload = () => {
        // 自动登录
        if (window.location.href.indexOf('cloud.huawei') !== -1) {
            // 浏览器记住密码的情况下
            setTimeout(() => {
                $('body').click()
            }, 1000)
            setTimeout(() => {
                $('.button-base-box').click()
            }, 2000)
        }
        // 提交订单
        if (window.location.href.indexOf('order') !== -1) {
            ec.order.confirmSubmit()
        }

        // 检查登录情况
        // 318 秒杀活动
        if (window.location.href.indexOf('/rush') !== -1) {
            if (ec.account.isLogin()) {
                const skuIds = ec.skuList.map((item) => { return item.skuInfo[0].id }).join(',')
                const getTime = new Date().getTime()
                getSkuRushbuyInfo(skuIds, getTime)
            } else {
                window.location.replace(ec.loginUrl)
            }
        }
        // 商城申购
        if (window.location.href.indexOf('/product') !== -1) {
            if (rush.account.isLogin()) {
                const skuIds = rush.sbom.getCurrSkuId()
                const getTime = new Date().getTime()
                getSkuRushbuyInfo(skuIds, getTime)
            } else {
                // ec.account.afterLogin()  弹窗登录
                rush.business.doGoLogin() //页面登录
            }
        }

    }

    let cycle = 0

    const initBox = () => {
            const style = `#rushToBuyBox{z-index: 9999;background-color:rgba(255,255,255,0.7);width:260px;font-size:14px;position:fixed;top:20%;right:-150px;padding:10px;border-radius:5px;box-shadow:1px 1px 9px 0 #888;transition:right 1s;text-align:center}#rushToBuyBox:hover{right:10px}.title{font-size:16px;font-weight:bold;margin:10px 0}.title span{font-size:12px;color:#9c9c9c}#formList{margin:10px}.time span{color:red}#formList input{background:0;height:20px;font-size:14px;outline:0;border:1px solid #ccc;margin-bottom:10px}#formList input:focus{border:1px solid #4ebd0d}#formList div span{font-size:12px;color:red}#formList div{margin-bottom:10px}.countdown{margin-top:10px}`
            const html = `
                    <div id='rushToBuyBox'>
                        <h3 class="title">
                            华为商城抢购助手 <span>by: Gorkys</span>
                        </h3>
                        <div class='time'>
                            <p>本地与服务器时间相差: <span id='offsetTime'>-1400ms</span></p>
                            <p>网络延迟: <span id='timer'>200ms</span></p>
                        </div>
                        <form id='formList'>
                            <div>活动开始时间</div>
                            <input type="text" id="g_startTime"  value="" placeholder="2020/03/07 12:49:00" />
                            <div>提前下单时间<span>(ms)</span></div>
                            <input type="number" id="g_beforeStartTime" value="" placeholder="200" /></br>
                            <div>提前刷新页面<span>(s)</span></div>
                            <input type="checkBox" id='isRefresh'> 开启</input>
                            <input style="margin-left:10px;width: 100px;" disabled id='refreshTime' type="number" /> 秒</br>
                            <button id='rushToBuy'>开始运行</button><button style='margin-left:5px' id='stop'>停止</button>
                        </form>
                        <div class='countdown'>倒计时: <span id='g_countdown'>1天 2:3:4</span></div>
                    </div>
                    `
            var stylenode = document.createElement('style');
            stylenode.setAttribute("type", "text/css");
            if (stylenode.styleSheet) { // IE
                stylenode.styleSheet.cssText = style;
            } else { // w3c
                var cssText = document.createTextNode(style);
                stylenode.appendChild(cssText);
            }
            var node = document.createElement('div');
            node.innerHTML = html;
            document.head.appendChild(stylenode);
            document.body.appendChild(node);

            const g_startTime = document.querySelector('#g_startTime')
            const g_beforeStartTime = document.querySelector('#g_beforeStartTime')
            const isRefresh = document.querySelector('#isRefresh')
            const refreshTime = document.querySelector('#refreshTime')
                // 设置活动开始时间
            g_startTime.value = formatTime(STARTTIME) || rush.activity.getActivity(rush.sbom.getCurrSkuId()).startTime
            g_beforeStartTime.value = 200
            refreshTime.value = 30
                // 延时
            document.querySelector('#offsetTime').innerText = OFFSETTIME || rush.business.offsetTime + 'ms'
            document.querySelector('#timer').innerText = NETWORKTIME || rush.business.timer + 'ms'


            // 倒计时
            const countdownId = setInterval(() => {
                document.querySelector('#g_countdown').innerText = getDistanceSpecifiedTime(g_startTime.value, new Date().getTime() + OFFSETTIME)
            }, 1000)

            const countdown = document.querySelector('#rushToBuy')
            const stop = document.querySelector('#stop')

            isRefresh.addEventListener('change', () => {
                sessionStorage.setItem('isRefresh', isRefresh.checked)
                refreshTime.disabled = !isRefresh.checked
            })

            countdown.addEventListener('click', () => {
                countdown.disabled = true
                countdown.innerText = '抢购中...'
                sessionStorage.setItem('g_startTime', g_startTime.value)
                sessionStorage.setItem('g_beforeStartTime', g_beforeStartTime.value)
                sessionStorage.setItem('isRun', true)

                getServerTime(g_startTime.value, g_beforeStartTime.value)
            })
            stop.addEventListener('click', () => {
                countdown.disabled = false
                countdown.innerText = '开始运行'
                sessionStorage.setItem('isRun', false)
                clearInterval(cycle)
            })

            if (sessionStorage.getItem('isRun') === 'true') {
                g_startTime.value = sessionStorage.getItem('g_startTime')
                g_beforeStartTime.value = sessionStorage.getItem('g_beforeStartTime')
                countdown.click()
            }
        }
        // 获取服务器时间
    const getServerTime = (g_startTime, g_beforeStartTime) => {
            const details = {
                method: 'GET',
                url: 'https://buy.vmall.com/getSkuRushbuyInfo.json',
                onload: (responseDetails) => {
                    if (responseDetails.status === 200) {
                        const res = JSON.parse(responseDetails.responseText)
                        const startTime = new Date(g_startTime).getTime()
                        const isRefresh = document.querySelector('#isRefresh')
                        const refreshTime = document.querySelector('#refreshTime')

                        let currentTime = res.currentTime
                        OFFSETTIME = new Date().getTime() - res.currentTime

                        cycle = setInterval(() => {
                            console.log(startTime - currentTime)
                            if (isRefresh.checked && startTime - currentTime <= refreshTime.value * 1000) {
                                sessionStorage.setItem('isRefresh', !isRefresh.checked)
                                window.location.reload()
                                clearInterval(cycle)
                            }

                            rushToBuy(startTime, currentTime, g_beforeStartTime)
                            currentTime += 10
                        }, 10)
                    }
                }
            }
            GM_xmlhttpRequest(details)
        }
        // 获取活动信息
    const getSkuRushbuyInfo = (skuIds, getTime) => {
            const details = {
                method: 'GET',
                url: `https://buy.vmall.com/getSkuRushbuyInfo.json?skuIds=${skuIds}&t=${new Date().getTime()}`,
                onload: (responseDetails) => {
                    if (responseDetails.status === 200) {
                        const res = JSON.parse(responseDetails.responseText)
                        NETWORKTIME = new Date().getTime() - getTime
                        OFFSETTIME = res.currentTime - new Date().getTime()
                        STARTTIME = res.skuRushBuyInfoList[0].startTime
                        initBox()
                    }
                }
            }
            GM_xmlhttpRequest(details)
        }
        // 提前申购
    const rushToBuy = (startTime, currentTime, g_beforeStartTime) => {
            if (startTime - currentTime <= g_beforeStartTime) {
                if (window.location.href.indexOf('/rush') !== -1) {
                    ec.submit(0)
                }
                if (window.location.href.indexOf('/product') !== -1) {
                    rush.business.doGoRush(1);
                }
                sessionStorage.setItem('isRun', false)
                clearInterval(cycle)
            }
        }
        // 抢购倒计时对比
    const getDistanceSpecifiedTime = (dateTime, currentTime) => {
            // 指定日期和时间
            var EndTime = new Date(dateTime).getTime();
            // 当前系统时间
            // var NowTime = new Date();
            // var t = EndTime.getTime() - NowTime.getTime();
            var t = EndTime - currentTime
            var d = Math.floor(t / 1000 / 60 / 60 / 24);
            var h = Math.floor(t / 1000 / 60 / 60 % 24);
            var m = Math.floor(t / 1000 / 60 % 60);
            var s = Math.floor(t / 1000 % 60);
            return `${fillZero(d)}天 ${fillZero(h)}:${fillZero(m)}:${fillZero(s)}`
        }
        // 格式化时间
    const formatTime = (time) => {
            var datetime = new Date();
            datetime.setTime(time);
            var year = datetime.getFullYear();
            var month = datetime.getMonth() + 1
            var date = datetime.getDate()
            var hour = datetime.getHours()
            var minute = datetime.getMinutes()
            var second = datetime.getSeconds()
            return `${year}-${fillZero(month)}-${fillZero(date)} ${fillZero(hour)}:${fillZero(minute)}:${fillZero(second)}`
        }
        // 补零
    const fillZero = (str, len = 2) => {
        return (`${str}`).padStart(len, '0')
            // return (`${str}`).slice(-len)
    }
})();