Greasy Fork

Greasy Fork is available in English.

华为商城抢购助手

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         华为商城抢购助手
// @namespace    https://github.com/gorkys/TampermonkeyHub
// @version      1.1.9
// @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
// @require      https://libs.baidu.com/jquery/2.1.4/jquery.min.js
// @grant        none
// ==/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) => {
        $.get('https://buy.vmall.com/getSkuRushbuyInfo.json', (res) => {
            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)
        })
    }
    // 获取活动信息
    const getSkuRushbuyInfo = (skuIds, getTime)=>{
        const params = {
            skuIds: skuIds,
            t: new Date().getTime()
        }
        $.get('https://buy.vmall.com/getSkuRushbuyInfo.json', params, (res) => {
            NETWORKTIME = new Date().getTime() - getTime
            OFFSETTIME = res.currentTime - new Date().getTime()
            STARTTIME = res.skuRushBuyInfoList[0].startTime
            initBox()
        })
    }
    // 提前申购
    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)
    }
})();