- // ==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();
-
- })();