Bundle Stars Keys Retrieve

Retrieve keys from Bundle Stars

目前为 2017-04-29 提交的版本。查看 最新版本

// ==UserScript==
// @name         Bundle Stars Keys Retrieve
// @namespace    http://tampermonkey.net/
// @version      1.2.0
// @description  Retrieve keys from Bundle Stars
// @icon         https://cdn.bundlestars.com/production/brand/apple-touch-icon-180x180.png
// @author       Bisumaruko
// @include      http*://*bundlestars.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    var $ = selector => document.querySelector(selector),
        $$ = selector => Array.from(document.querySelectorAll(selector));

    function getAnchor() {
        var anchor = $('h2');

        return anchor && anchor.textContent.trim() === 'Order Keys' ? anchor : null;
    }

    function setup() {
        var anchor = getAnchor();

        if (!anchor) return;

        var style = document.createElement('style');

        style.type = 'text/css';
        style.innerHTML = `
            .BSRetrive {
                width: 100%;
                height: 200px;
                display: flex;
                flex-direction: column;
                box-sizing: border-box;
                border: 1px solid #424242;
                color: #999999;
            }
            .BSRetrive > textarea {
                width: 100%;
                height: 150px;
                border: none;
                background-color: #303030;
                color: #DDD;
                box-sizing: border-box;
                resize: none;
            }
            .BSRetrive > div {
                width: 100%;
                padding-top: 5px;
                box-sizing: border-box;
            }
            .BSRetrive > div > button, .BSRetrive select {
                height: 34px;
                margin-right: 10px;
                padding: 6px 12px;
                border: 1px solid transparent;
                background-color: #262626;
                color: #dedede;
                box-sizing: border-box;
                outline: none;
                cursor: pointer;
            }
            .BSRetrive > div > button:hover, .BSRetrive select:hover {
                color: #A8A8A8;
            }
            .BSRetrive > div > label {
                margin-right: 10px;
                color: #dedede;
            }
            .BSRetrive select, .BSRetrive span {
                margin-right: 0;
                margin-left: 10px;
                float: right;
            }
            .BSRetrive span {
                margin-top: 5px;
            }
        `;

        document.head.appendChild(style);

        var qsAll = function (selector) {
            let doms = [],
                from = parseInt(BSSelectFrom.value),
                to = parseInt(BSSelectTo.value);

            if (isNaN(from) || isNaN(to)) {
                msg.alert('An error occured, please refresh the page');
                return null;
            }

            if (from === 0 && to > 0) from = 1;
            if (from > 0 && to === 0) to = pool.length - 1;

            for (var index = Math.min(from, to); index <= Math.max(from, to); index++) {
                let node = pool[index],
                    _doms = !node || Array.from(node.querySelectorAll(selector));

                if (_doms) doms = doms.concat(_doms);
            }

            return doms;
        };

        var BSRetrive = document.createElement('div'),
            BSTextarea = document.createElement('textarea'),
            BSDiv = document.createElement('div'),
            BSBtnReveal = document.createElement('button'),
            BSBtnRetrieve = document.createElement('button'),
            BSBtnCopy = document.createElement('button'),
            BSBtnReset = document.createElement('button'),
            BSCheckTitle = document.createElement('label'),
            BSCheckJoin = document.createElement('label'),
            BSSelectFrom = document.createElement('select'),
            BSSelectTo;

        BSRetrive.className = 'BSRetrive';
        BSBtnReveal.textContent = 'Reveal';
        BSBtnRetrieve.textContent = 'Retrieve';
        BSBtnCopy.textContent = 'Copy';
        BSBtnReset.textContent = 'Reset';
        BSCheckTitle.innerHTML = '<input type="checkbox" class="BSCheckTitle">Include Game Title';
        BSCheckJoin.innerHTML = '<input type="checkbox" class="BSCheckJoin">Join Keys';

        BSBtnReveal.addEventListener('click', () => {
            let keys = qsAll('.key-container a[ng-click^="redeemSerial"]');

            if (!keys) {
                msg.alert('Empty search, please select the correct options');
                return;
            }

            for (let key of keys) {
                if (!key.closest('.ng-hide')) key.click();
            }
        });

        BSBtnRetrieve.addEventListener('click', () => {
            let keys = [],
                containers = qsAll('.key-container'),
                separator = $('.BSCheckJoin').checked ? ',' : "\n";

            if (!containers) {
                msg.alert('Empty search, please select the correct options');
                return;
            }

            for (let container of containers) {
                let key = container.querySelector('input'),
                    title = container.previousElementSibling;

                if (!key) continue;

                key = key.value.trim();
                if (title && $('.BSCheckTitle').checked) key = title.textContent.trim() + ', ' + key;
                keys.push(key);
            }

            BSTextarea.textContent = keys.join(separator);
        });

        BSBtnCopy.addEventListener('click', () => {
            BSTextarea.select();
    		document.execCommand('copy');
        });

        BSBtnReset.addEventListener('click', () => {
            BSTextarea.textContent = '';
        });

        let pool = [document];

        setTimeout(() => {
            let blocks = $$('hr ~ div > div:not(.ng-hide)');

            BSSelectFrom.appendChild(new Option('All', 0));

            for (let block of blocks) {
                let option,
                    bundle = block.querySelector('h3'),
                    tiers = Array.from(block.querySelectorAll('h4'));

                if (tiers.length > 1) { //bundles (multiple tiers)
                    let title = bundle.textContent;

                    for (let tier of tiers) {
                        option = new Option(title + ' ' + tier.textContent, pool.push(tier.parentNode) - 1);
                        BSSelectFrom.appendChild(option);
                    }
                } else if (bundle) { //bundles (single tier)
                    option = new Option(bundle.textContent, pool.push(bundle.nextElementSibling ) - 1);
                    BSSelectFrom.appendChild(option);
                } else { //individual games
                    option = new Option(block.querySelector('.title').textContent, pool.push(block) - 1);
                    BSSelectFrom.appendChild(option);
                }
            }

            BSSelectTo = BSSelectFrom.cloneNode(true);
            let span = document.createElement('span');

            span.textContent = 'to';

            BSDiv.appendChild(BSSelectTo);
            BSDiv.appendChild(span);
            BSDiv.appendChild(BSSelectFrom);
        }, 1000);

        BSDiv.appendChild(BSBtnReveal);
        BSDiv.appendChild(BSBtnRetrieve);
        BSDiv.appendChild(BSBtnCopy);
        BSDiv.appendChild(BSBtnReset);
        BSDiv.appendChild(BSCheckTitle);
        BSDiv.appendChild(BSCheckJoin);
        BSRetrive.appendChild(BSTextarea);
        BSRetrive.appendChild(BSDiv);
        anchor.parentNode.insertBefore(BSRetrive, anchor);
    }

    function observeOrderDetails(target) {
        new MutationObserver(mutations => {
            for (let mutation of mutations) {
                if (!mutation.addedNodes.length) continue;
                if (mutation.addedNodes[0].classList.contains('ng-scope')) setup();
            }
        }).observe(target, {childList: true});
    }

    var anchor = getAnchor();

    if (anchor) {
        setup();
        observeOrderDetails(anchor.closest('body > div.ng-scope'));
    } else {
        var bodyObserver = new MutationObserver(mutations => {
            for (let mutation of mutations) {
                if (!mutation.addedNodes.length) continue;
                if (mutation.addedNodes[0].classList.contains('ng-scope')) {
                    observeOrderDetails(mutation.addedNodes[0]);
                    bodyObserver.disconnect();
                }
            }
        });

        bodyObserver.observe(document.body, {childList: true});
    }

    var msg = {
        box: null,
        init() {
            var style = document.createElement('style');

            style.type = 'text/css';
            style.innerHTML = `
                .BSRetrive_msg {
                    display: none;
                    position: fixed;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    padding: 10px 20px;
                    border: 1px solid #424242;
                    background-color: rgb(32, 32, 32);
                    color: #FFF;
                    font-size: larger;
                }
                .BSRetrive_msg-show {
                    display: block;
                }
            `;
            document.head.appendChild(style);

            var BSRetrive_msg = document.createElement('div');

            BSRetrive_msg.classList.add('BSRetrive_msg');
            document.body.appendChild(BSRetrive_msg);
            this.box = BSRetrive_msg;
        },
        alert(text) {
            this.box.textContent = text;
            this.box.classList.add('BSRetrive_msg-show');
            setTimeout(this.hide.bind(this), 3000);
        },
        hide() {
            this.box.classList.remove('BSRetrive_msg-show');
        }
    };

    msg.init();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址