Bundle Stars Keys Retrieve

Retrieve keys from Bundle Stars

目前為 2017-04-29 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Bundle Stars Keys Retrieve
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.2.0
  5. // @description Retrieve keys from Bundle Stars
  6. // @icon https://cdn.bundlestars.com/production/brand/apple-touch-icon-180x180.png
  7. // @author Bisumaruko
  8. // @include http*://*bundlestars.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. var $ = selector => document.querySelector(selector),
  16. $$ = selector => Array.from(document.querySelectorAll(selector));
  17.  
  18. function getAnchor() {
  19. var anchor = $('h2');
  20.  
  21. return anchor && anchor.textContent.trim() === 'Order Keys' ? anchor : null;
  22. }
  23.  
  24. function setup() {
  25. var anchor = getAnchor();
  26.  
  27. if (!anchor) return;
  28.  
  29. var style = document.createElement('style');
  30.  
  31. style.type = 'text/css';
  32. style.innerHTML = `
  33. .BSRetrive {
  34. width: 100%;
  35. height: 200px;
  36. display: flex;
  37. flex-direction: column;
  38. box-sizing: border-box;
  39. border: 1px solid #424242;
  40. color: #999999;
  41. }
  42. .BSRetrive > textarea {
  43. width: 100%;
  44. height: 150px;
  45. border: none;
  46. background-color: #303030;
  47. color: #DDD;
  48. box-sizing: border-box;
  49. resize: none;
  50. }
  51. .BSRetrive > div {
  52. width: 100%;
  53. padding-top: 5px;
  54. box-sizing: border-box;
  55. }
  56. .BSRetrive > div > button, .BSRetrive select {
  57. height: 34px;
  58. margin-right: 10px;
  59. padding: 6px 12px;
  60. border: 1px solid transparent;
  61. background-color: #262626;
  62. color: #dedede;
  63. box-sizing: border-box;
  64. outline: none;
  65. cursor: pointer;
  66. }
  67. .BSRetrive > div > button:hover, .BSRetrive select:hover {
  68. color: #A8A8A8;
  69. }
  70. .BSRetrive > div > label {
  71. margin-right: 10px;
  72. color: #dedede;
  73. }
  74. .BSRetrive select, .BSRetrive span {
  75. margin-right: 0;
  76. margin-left: 10px;
  77. float: right;
  78. }
  79. .BSRetrive span {
  80. margin-top: 5px;
  81. }
  82. `;
  83.  
  84. document.head.appendChild(style);
  85.  
  86. var qsAll = function (selector) {
  87. let doms = [],
  88. from = parseInt(BSSelectFrom.value),
  89. to = parseInt(BSSelectTo.value);
  90.  
  91. if (isNaN(from) || isNaN(to)) {
  92. msg.alert('An error occured, please refresh the page');
  93. return null;
  94. }
  95.  
  96. if (from === 0 && to > 0) from = 1;
  97. if (from > 0 && to === 0) to = pool.length - 1;
  98.  
  99. for (var index = Math.min(from, to); index <= Math.max(from, to); index++) {
  100. let node = pool[index],
  101. _doms = !node || Array.from(node.querySelectorAll(selector));
  102.  
  103. if (_doms) doms = doms.concat(_doms);
  104. }
  105.  
  106. return doms;
  107. };
  108.  
  109. var BSRetrive = document.createElement('div'),
  110. BSTextarea = document.createElement('textarea'),
  111. BSDiv = document.createElement('div'),
  112. BSBtnReveal = document.createElement('button'),
  113. BSBtnRetrieve = document.createElement('button'),
  114. BSBtnCopy = document.createElement('button'),
  115. BSBtnReset = document.createElement('button'),
  116. BSCheckTitle = document.createElement('label'),
  117. BSCheckJoin = document.createElement('label'),
  118. BSSelectFrom = document.createElement('select'),
  119. BSSelectTo;
  120.  
  121. BSRetrive.className = 'BSRetrive';
  122. BSBtnReveal.textContent = 'Reveal';
  123. BSBtnRetrieve.textContent = 'Retrieve';
  124. BSBtnCopy.textContent = 'Copy';
  125. BSBtnReset.textContent = 'Reset';
  126. BSCheckTitle.innerHTML = '<input type="checkbox" class="BSCheckTitle">Include Game Title';
  127. BSCheckJoin.innerHTML = '<input type="checkbox" class="BSCheckJoin">Join Keys';
  128.  
  129. BSBtnReveal.addEventListener('click', () => {
  130. let keys = qsAll('.key-container a[ng-click^="redeemSerial"]');
  131.  
  132. if (!keys) {
  133. msg.alert('Empty search, please select the correct options');
  134. return;
  135. }
  136.  
  137. for (let key of keys) {
  138. if (!key.closest('.ng-hide')) key.click();
  139. }
  140. });
  141.  
  142. BSBtnRetrieve.addEventListener('click', () => {
  143. let keys = [],
  144. containers = qsAll('.key-container'),
  145. separator = $('.BSCheckJoin').checked ? ',' : "\n";
  146.  
  147. if (!containers) {
  148. msg.alert('Empty search, please select the correct options');
  149. return;
  150. }
  151.  
  152. for (let container of containers) {
  153. let key = container.querySelector('input'),
  154. title = container.previousElementSibling;
  155.  
  156. if (!key) continue;
  157.  
  158. key = key.value.trim();
  159. if (title && $('.BSCheckTitle').checked) key = title.textContent.trim() + ', ' + key;
  160. keys.push(key);
  161. }
  162.  
  163. BSTextarea.textContent = keys.join(separator);
  164. });
  165.  
  166. BSBtnCopy.addEventListener('click', () => {
  167. BSTextarea.select();
  168. document.execCommand('copy');
  169. });
  170.  
  171. BSBtnReset.addEventListener('click', () => {
  172. BSTextarea.textContent = '';
  173. });
  174.  
  175. let pool = [document];
  176.  
  177. setTimeout(() => {
  178. let blocks = $$('hr ~ div > div:not(.ng-hide)');
  179.  
  180. BSSelectFrom.appendChild(new Option('All', 0));
  181.  
  182. for (let block of blocks) {
  183. let option,
  184. bundle = block.querySelector('h3'),
  185. tiers = Array.from(block.querySelectorAll('h4'));
  186.  
  187. if (tiers.length > 1) { //bundles (multiple tiers)
  188. let title = bundle.textContent;
  189.  
  190. for (let tier of tiers) {
  191. option = new Option(title + ' ' + tier.textContent, pool.push(tier.parentNode) - 1);
  192. BSSelectFrom.appendChild(option);
  193. }
  194. } else if (bundle) { //bundles (single tier)
  195. option = new Option(bundle.textContent, pool.push(bundle.nextElementSibling ) - 1);
  196. BSSelectFrom.appendChild(option);
  197. } else { //individual games
  198. option = new Option(block.querySelector('.title').textContent, pool.push(block) - 1);
  199. BSSelectFrom.appendChild(option);
  200. }
  201. }
  202.  
  203. BSSelectTo = BSSelectFrom.cloneNode(true);
  204. let span = document.createElement('span');
  205.  
  206. span.textContent = 'to';
  207.  
  208. BSDiv.appendChild(BSSelectTo);
  209. BSDiv.appendChild(span);
  210. BSDiv.appendChild(BSSelectFrom);
  211. }, 1000);
  212.  
  213. BSDiv.appendChild(BSBtnReveal);
  214. BSDiv.appendChild(BSBtnRetrieve);
  215. BSDiv.appendChild(BSBtnCopy);
  216. BSDiv.appendChild(BSBtnReset);
  217. BSDiv.appendChild(BSCheckTitle);
  218. BSDiv.appendChild(BSCheckJoin);
  219. BSRetrive.appendChild(BSTextarea);
  220. BSRetrive.appendChild(BSDiv);
  221. anchor.parentNode.insertBefore(BSRetrive, anchor);
  222. }
  223.  
  224. function observeOrderDetails(target) {
  225. new MutationObserver(mutations => {
  226. for (let mutation of mutations) {
  227. if (!mutation.addedNodes.length) continue;
  228. if (mutation.addedNodes[0].classList.contains('ng-scope')) setup();
  229. }
  230. }).observe(target, {childList: true});
  231. }
  232.  
  233. var anchor = getAnchor();
  234.  
  235. if (anchor) {
  236. setup();
  237. observeOrderDetails(anchor.closest('body > div.ng-scope'));
  238. } else {
  239. var bodyObserver = new MutationObserver(mutations => {
  240. for (let mutation of mutations) {
  241. if (!mutation.addedNodes.length) continue;
  242. if (mutation.addedNodes[0].classList.contains('ng-scope')) {
  243. observeOrderDetails(mutation.addedNodes[0]);
  244. bodyObserver.disconnect();
  245. }
  246. }
  247. });
  248.  
  249. bodyObserver.observe(document.body, {childList: true});
  250. }
  251.  
  252. var msg = {
  253. box: null,
  254. init() {
  255. var style = document.createElement('style');
  256.  
  257. style.type = 'text/css';
  258. style.innerHTML = `
  259. .BSRetrive_msg {
  260. display: none;
  261. position: fixed;
  262. top: 50%;
  263. left: 50%;
  264. transform: translate(-50%, -50%);
  265. padding: 10px 20px;
  266. border: 1px solid #424242;
  267. background-color: rgb(32, 32, 32);
  268. color: #FFF;
  269. font-size: larger;
  270. }
  271. .BSRetrive_msg-show {
  272. display: block;
  273. }
  274. `;
  275. document.head.appendChild(style);
  276.  
  277. var BSRetrive_msg = document.createElement('div');
  278.  
  279. BSRetrive_msg.classList.add('BSRetrive_msg');
  280. document.body.appendChild(BSRetrive_msg);
  281. this.box = BSRetrive_msg;
  282. },
  283. alert(text) {
  284. this.box.textContent = text;
  285. this.box.classList.add('BSRetrive_msg-show');
  286. setTimeout(this.hide.bind(this), 3000);
  287. },
  288. hide() {
  289. this.box.classList.remove('BSRetrive_msg-show');
  290. }
  291. };
  292.  
  293. msg.init();
  294.  
  295. })();

QingJ © 2025

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