AcFun - 爱咔号查询

修改0.0伪爱咔号的爱咔剪辑页面样式,添加爱咔号查询功能

// ==UserScript==
// @name         AcFun - 爱咔号查询
// @namespace    http://tampermonkey.net/
// @version      1.0.3
// @description  修改0.0伪爱咔号的爱咔剪辑页面样式,添加爱咔号查询功能
// @author       dareomaewa
// @match        https://onvideo.kuaishou.com/vangogh/editor/0.0?source=ac
// @icon         https://www.google.com/s2/favicons?sz=64&domain=acfun.cn
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.0/jquery-1.8.0.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.5/dayjs.min.js
// @license MIT
// ==/UserScript==


(function() {
    'use strict';

    var findCanceled = false;

    function waitElement(selector, times, interval, flag=true){
        var _times = times || -1,
            _interval = interval || 1,
            _selector = selector,
            _iIntervalID,
            _flag = flag;
        return new Promise(function(resolve, reject){
            _iIntervalID = setInterval(function() {
                if(!_times) {
                    clearInterval(_iIntervalID);
                    reject();
                }
                _times <= 0 || _times--;
                var _self = $(_selector);
                if( (_flag && _self.length) || (!_flag && !_self.length) ) {
                    clearInterval(_iIntervalID);
                    resolve(_iIntervalID);
                }
            }, _interval);
        });
    }

    function addChild(fatherNode, childNode, innerHtmlStr, type) {
        childNode.innerHTML = innerHtmlStr;
        if (type) {
            if (type === 'prepend') {
                fatherNode.prepend(childNode);
            }
            else {
                fatherNode.appendChild(childNode);
            }
        }else {
            fatherNode.appendChild(childNode.childNodes[0]);
        }
    }

    function replaceText(selector, newText) {
        waitElement(selector).then(function() {document.querySelector(selector).innerText = newText;});
    }

    function removeNode(selector) {
        waitElement(selector).then(function() {document.querySelector(selector).remove();});
    }

    function findAikaTime(btnSelector) {
        const btn = document.querySelector(btnSelector);

        const tips = document.querySelector(btnSelector + '_tips');
        tips.innerText = '';

        var aikaValue = document.querySelector(btnSelector +'_text').value;
        aikaValue = aikaValue.trim();
        if (!(/^\d+$/.test(aikaValue))) {
            tips.innerText = '请输入有效爱咔号,规则:纯数字';
            return;
        }
        $.ajax({
            url: 'https://onvideoapi.kuaishou.com/api/live/get_channel/' + aikaValue + '?source=ac',
            type: 'get',
            xhrFields: {
                withCredentials: true
            },
            success: function (res, status, xhr) {
                console.log(res);
                if (res.code === 200) {
                    tips.innerText = dayjs(res.data.startTime).format("YYYY-MM-DD HH:mm:ss");
                }
                else {
                    tips.innerText = res.code + ': ' + res.msg;
                }
            },
            error: function (res, status, xhr) {
                tips.innerText = xhr.status + ': ' + status;
            },
            beforeSend: function() {
                btn.disabled = true;
                btn.style['background-color'] = 'rgb(0 0 0 / 45%)';
                btn.innerText = '查询中…';
            },
            complete: function() {
                btn.disabled = false;
                btn.style['background-color'] = '#fd4c5d';
                btn.innerText = '查询时间';
            }
        });
    }

    window.checkStartTime = function checkStartTime() {
        findAikaTime('#check_start_time');
    }

    window.checkEndTime = function checkEndTime() {
        findAikaTime('#check_end_time');
    }

    function wait(ms) {
        return new Promise(resolve =>setTimeout(() => resolve(), ms));
    };

    window.aikaCut = function aikaCut(aikaNo) {
        const btn = document.querySelector('#aikaCut_' + aikaNo);
        btn.disabled = true;
        btn.style['background-color'] = 'rgb(0 0 0 / 45%)';
        btn.innerText = '跳转中…';

        const aikaA = document.createElement('a');
                aikaA.href = 'https://onvideo.kuaishou.com/vangogh/editor/' + aikaNo + '?source=ac';
                aikaA.target = '_blank';
                aikaA.click();
                aikaA.remove();

        btn.disabled = false;
        btn.style['background-color'] = '#fd4c5d';
        btn.innerText = '爱咔剪辑';
    }

    window.cancelfindAika = async function cancelfindAika() {
        console.log('取消查询');
        if(confirm(`确定要取消查询吗?`)) {
            findCanceled = true;
        }
    }

    window.findAika = async function findAika() {
        findCanceled = false;
        const tips = document.querySelector('#find_aika_tips');
        tips.innerText = '';
        await wait(100);
        var startAikaValue = document.querySelector('#check_start_time_text').value;
        startAikaValue = startAikaValue.trim();
        if (!(/^\d+$/.test(startAikaValue))) {
            tips.innerText = '请在“开始爱咔号”中输入有效爱咔号,规则:纯数字';
            return;
        }

        var endAikaValue = document.querySelector('#check_end_time_text').value;
        endAikaValue = endAikaValue.trim();
        const hasEndAika = endAikaValue && endAikaValue.length > 0;
        if(hasEndAika) {
            if (!(/^\d+$/.test(endAikaValue))) {
                tips.innerText = '请在“结束爱咔号”中输入有效爱咔号,规则:纯数字。或者清空';
                return;
            }
            if (startAikaValue > endAikaValue) {
                tips.innerText = '“开始爱咔号”不能大于“结束爱咔号”';
                return;
            }
            if (parseInt(endAikaValue) - parseInt(startAikaValue) > 200) {
                tips.innerText = ' 开始~结束 区间不能大于200';
                return;
            }
            endAikaValue = parseInt(endAikaValue);
        }
        else {
            const range = document.querySelector('#range').value;
            endAikaValue = parseInt(startAikaValue) + parseInt(range) - 1;
        }

        var uidTextValue = document.querySelector('#uid_text').value;
        uidTextValue = uidTextValue.trim();
        const onlyOneUid = /^\d+$/.test(uidTextValue);
        const filterUids = [];
        if (onlyOneUid) {
            filterUids.push(uidTextValue);
        }
        else if(uidTextValue && uidTextValue.length > 0) {
            uidTextValue = uidTextValue.replaceAll(",", ",").replaceAll(" ", ",");
            const uids = uidTextValue.split(',');
            uids.forEach(uid => {
                uid = uid.trim();
                if (/^\d+$/.test(uid) && !filterUids.some((fuid) => fuid == uid)) {
                    filterUids.push(uid);
                }
            });
        }
        console.log(filterUids);
        console.log(`startAikaValue: ${startAikaValue}, endAikaValue: ${endAikaValue}`);

        const onlyOneAikaNo = endAikaValue == startAikaValue;
        const hasFilterUids = filterUids.length > 0;
        if(!hasFilterUids) {
            tips.innerText = '查找中… (本次查找无过滤uid,原因:uid为空或者不符合规则)';
        }
        else {
            tips.innerText = '查找中…';
        }

        const findResults =document.querySelector('#findResults');
        findResults.innerText = '';
        const findAikaBtn =document.querySelector('#findAika');
        findAikaBtn.style['background-color'] = '#e6e6e6';
        findAikaBtn.style.color = '#666666';
        findAikaBtn.onclick = window.cancelfindAika;
        findAikaBtn.innerText = '取消查询'

        for (var i = startAikaValue,count = 1; i <= endAikaValue; i++,count++) {
            if (findCanceled) {
                tips.innerText = '查询已取消';
                findAikaBtn.style['background-color'] = '#fd4c5d';
                findAikaBtn.style.color = '#fff';
                findAikaBtn.onclick = window.findAika;
                findAikaBtn.innerText = '确认查询'
                break;
            }
            await wait(100);
            $.ajax({
                async:false,
                url: 'https://onvideoapi.kuaishou.com/api/live/get_channel/' + i + '?source=ac',
                type: 'get',
                xhrFields: {
                    withCredentials: true
                },
                success: function (res, status, xhr) {
                    console.log(res);
                    if (res.code === 200) {
                        if (hasFilterUids) {
                            if (!filterUids.some((fuid) => fuid == res.data.ksUserId)) {
                                return;
                            }
                        }
                        const findResult = `
                        <div style="padding: 5px;font-size: 12px;border: 1px solid #e5e5e5;line-height: 20px;vertical-align: top;color: #999;box-sizing: border-box;margin-top: 5px;position: relative;">
                            <p>状态:${res.code + ' - ' + res.msg}</p>
                            <p>爱咔号:${res.data.streamId}</p>
                            <p>uid:${res.data.ksUserId}</p>
                            <p>主播:${res.data.nickname}</p>
                            <p>开播时间:${dayjs(res.data.startTime).format("YYYY-MM-DD HH:mm:ss")}</p>
                            <p>结束时间:${res.data.endTime ? dayjs(res.data.endTime).format("YYYY-MM-DD HH:mm:ss") : '直播中'}</p>
                            <p>标题:${res.data.name}</p>
                            <span style="
                                position: absolute;
                                top: 0px;
                                right: 0px;
                                padding: 0 10px;
                                color: rgb(38, 185, 99);">${count}</span>
                            <div style="padding: 10px 0 0 0;position: absolute;bottom: 0px;right: 0px;padding: 5px 10px;">
                                <button id="aikaCut_${res.data.streamId}" onclick="window.aikaCut(${res.data.streamId});" style="
                                    display: inline-block;
                                    background-color: #fd4c5d;
                                    width: 74px;
                                    height: 26px;
                                    text-indent: 4px;
                                    text-align: left;
                                    text-indent: 10px;
                                    color: #fff;
                                    font-size: 14px;
                                    line-height: 26px;
                                    border-radius: 4px;">爱咔剪辑
                                </button>
                            </div>
                        </div>`;
                        addChild(findResults, document.createElement("div"), findResult, 'prepend');
                    }
                    else {
                        if(onlyOneAikaNo) {
                            const findResult = `
                            <div style="padding: 5px;font-size: 12px;border: 1px solid #e5e5e5;line-height: 20px;vertical-align: top;color: #999;box-sizing: border-box;margin-top: 5px;position: relative;">
                                <p>状态:${res.code + ' - ' + res.msg}</p>
                                <p>爱咔号:${i}</p>
                            </div>`;
                            addChild(findResults, document.createElement("div"), findResult, 'prepend');
                        }
                    }
                }
            });
            if (i == endAikaValue) {
                tips.innerText = '查找结束';
                findAikaBtn.style['background-color'] = '#fd4c5d';
                findAikaBtn.style.color = '#fff';
                findAikaBtn.onclick = window.findAika;
                findAikaBtn.innerText = '确认查询'
            }
        }
    }

    replaceText('title', '爱咔号查询');
    removeNode('.ant-message');

    waitElement('#root').then(function() {
        document.querySelector('#root').remove();
        waitElement('body').then(function() {
            const htmlStr = `
<div style="
        position: absolute;
        z-index: 9999;
        left: 50%;
        top: 40%;
        transform: translateX(-50%) translateY(-50%);
        width: 50%;
        height: 65%;
        background-color: white;
        padding: 20px 0 40px 0;
        overflow: auto;
        ">
    <div style="
        position: relative;
        z-index: 9999;
        left: 50%;
        transform: translateX(-50%);
        width: 80%;
        ">
        <h1 style="font-size: 20px;">爱咔号查询</h1>
    </div>
    <div style="
        position: relative;
        z-index: 9999;
        left: 50%;
        transform: translateX(-50%);
        width: 80%;
        padding: 10px 0 0 0;
        ">
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <span style="
                padding: 10px 0 0 0;">
                开始爱咔号
                <span style="
                    padding: 0 0 0 5px;
                    color: red;">
                    *
                </span>
            </span>
        </div>
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div style="padding: 5px 0 0 0;">
                <input type="text" placeholder="开始爱咔号" value="" autocomplete="off" id="check_start_time_text" style="
                    width: 100%;
                    padding: 8px 30px 8px 10px;
                    height: 36px;
                    font-size: 12px;
                    border: 1px solid #e5e5e5;
                    line-height: 14px;
                    vertical-align: top;
                    color: #999;
                    box-sizing: border-box;">
            </div>
        </div>
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div>
                <div style="padding: 10px 0 0 0;position: relative;">
                    <button id="check_start_time" onclick="window.checkStartTime();" style="
                        display: inline-block;
                        background-color: #fd4c5d;
                        width: 74px;
                        height: 26px;
                        text-indent: 4px;
                        text-align: left;
                        text-indent: 10px;
                        color: #fff;
                        font-size: 14px;
                        line-height: 26px;
                        border-radius: 4px;">查询时间
                    </button>
                    <span id="check_start_time_tips" style="
                        padding-left: 10px;
                        color: rgb(38, 185, 99);">
                    </span>
                </div>
            </div>
        </div>
    </div>
    <div style="
        position: relative;
        z-index: 9999;
        left: 50%;
        transform: translateX(-50%);
        width: 80%;
        padding: 10px 0 0 0;
        ">
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <span style="
                padding: 10px 0 0 0;">
                结束爱咔号 - 开始~结束 不能超过最大查询范围200
            </span>
        </div>
        <div style="
        position: relative;
        z-index: 9999;
        left: 50%;
        top: 0;
        transform: translateX(-50%);
        width: 80%;
        ">
            <div style="padding: 5px 0 0 0;">
                <input type="text" placeholder="结束爱咔号" value="" autocomplete="off" id="check_end_time_text" style="
                width: 100%;
                padding: 8px 30px 8px 10px;
                height: 36px;
                font-size: 12px;
                border: 1px solid #e5e5e5;
                line-height: 14px;
                vertical-align: top;
                color: #999;
                box-sizing: border-box;">
            </div>
        </div>
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div>
                <div style="padding: 10px 0 0 0;position: relative;">
                    <button id="check_end_time" onclick="window.checkEndTime();" style="
                        display: inline-block;
                        background-color: #fd4c5d;
                        width: 74px;
                        height: 26px;
                        text-indent: 4px;
                        text-align: left;
                        text-indent: 10px;
                        color: #fff;
                        font-size: 14px;
                        line-height: 26px;
                        border-radius: 4px;">查询时间
                    </button>
                    <span id="check_end_time_tips" style="
                        padding-left: 10px;
                        color: rgb(38, 185, 99);">
                    </span>
                </div>
            </div>
        </div>
    </div>
    <div style="
        position: relative;
        z-index: 9999;
        left: 50%;
        transform: translateX(-50%);
        width: 80%;
        padding: 10px 0 0 0;
        ">
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <span style="
            padding: 10px 0 0 0;">
                查询范围 - 1~200。如果有填“结束爱咔号”,那么查询范围为 开始~结束 的区间
            </span>
        </div>
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div style="padding: 5px 0 0 0;">
                <input type="number" placeholder="查询范围大小,默认200,最大200" value="200" autocomplete="off" id="range" style="
                    width: 100%;
                    padding: 8px 30px 8px 10px;
                    height: 36px;
                    font-size: 12px;
                    border: 1px solid #e5e5e5;
                    line-height: 14px;
                    vertical-align: top;
                    color: #999;
                    box-sizing: border-box;" oninput="if(value>200)value=200;if(value.length>3)value=value.slice(0,3);if(value<1)value=1">
            </div>
        </div>
    </div>
    <div style="
        position: relative;
        z-index: 9999;
        left: 50%;
        transform: translateX(-50%);
        width: 80%;
        padding: 10px 0 0 0;
        ">
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <span style="
            padding: 10px 0 0 0;">
                查询uid - 可以查询单个或多个,多个uid通过“,”(英文逗号) 或者 “ ”(空格) 来分隔
            </span>
        </div>
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div style="padding: 5px 0 0 0;">
                <input type="text" placeholder="123 或者 123,456,789" value="" autocomplete="off" id="uid_text" style="
                    width: 100%;
                    padding: 8px 30px 8px 10px;
                    height: 36px;
                    font-size: 12px;
                    border: 1px solid #e5e5e5;
                    line-height: 14px;
                    vertical-align: top;
                    color: #999;
                    box-sizing: border-box;">
            </div>
        </div>
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div>
                <div style="padding: 10px 0 0 0;position: relative;">
                    <button id="findAika" onclick="window.findAika();" style="
                        display: inline-block;
                        background-color: #fd4c5d;
                        width: 74px;
                        height: 26px;
                        text-indent: 4px;
                        text-align: left;
                        text-indent: 10px;
                        color: #fff;
                        font-size: 14px;
                        line-height: 26px;
                        border-radius: 4px;">确认查询</button>
                    <span id="find_aika_tips" style="
                        padding-left: 10px;
                        color: rgb(38, 185, 99);">
                    </span>
                </div>
            </div>
        </div>
    </div>
    <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            transform: translateX(-50%);
            width: 80%;
            padding: 10px 0 0 0;
        ">
        <div style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <span style="
        padding: 10px 0 5px 0;">
                查询结果
            </span>
        </div>
        <div  id="findResults" style="
            position: relative;
            z-index: 9999;
            left: 50%;
            top: 0;
            transform: translateX(-50%);
            width: 80%;
            ">
            <div style="padding: 5px;font-size: 12px;border: 1px solid #e5e5e5;line-height: 20px;vertical-align: top;color: #999;box-sizing: border-box;margin-top: 5px;">
                <p>状态:</p>
                <p>爱咔号:</p>
                <p>uid:</p>
                <p>主播:</p>
                <p>开播时间:</p>
                <p>结束时间:</p>
                <p>标题:</p>
            </div>
        </div>
    </div>
</div>
        `;
            const body =document.querySelector('body');
            body.style=`
                background: linear-gradient(0deg,#fff 0,hsla(0,0%,100%,0) 200px,hsla(0,0%,100%,0) 200.1px,hsla(0,0%,100%,0)),url(//static.yximgs.com/udata/pkg/acfun-fe/bg.png);
                background-position: 50%;
                background-size: cover;`
            addChild(body, document.createElement("div"), htmlStr, 'div');
        });
    });

})();