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.3.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. BSRetrive = {};
  18.  
  19. BSRetrive.init = function () {
  20. var style = document.createElement('style');
  21.  
  22. style.type = 'text/css';
  23. style.innerHTML = `
  24. .BSRetrive {
  25. width: 100%;
  26. height: 200px;
  27. display: flex;
  28. flex-direction: column;
  29. box-sizing: border-box;
  30. border: 1px solid #424242;
  31. color: #999999;
  32. }
  33. .BSRetrive > textarea {
  34. width: 100%;
  35. height: 150px;
  36. border: none;
  37. background-color: #303030;
  38. color: #DDD;
  39. box-sizing: border-box;
  40. resize: none;
  41. }
  42. .BSRetrive > div {
  43. width: 100%;
  44. padding-top: 5px;
  45. box-sizing: border-box;
  46. }
  47. .BSRetrive button, .BSRetrive select {
  48. height: 34px;
  49. margin-right: 10px;
  50. padding: 6px 12px;
  51. border: 1px solid transparent;
  52. background-color: #262626;
  53. color: #DEDEDE;
  54. box-sizing: border-box;
  55. outline: none;
  56. cursor: pointer;
  57. }
  58. .BSRetrive button:hover, .BSRetrive select:hover {
  59. color: #A8A8A8;
  60. }
  61. .BSRetrive label {
  62. margin-right: 10px;
  63. color: #DEDEDE;
  64. }
  65. .BSRetrive select {
  66. max-width:200px;
  67. }
  68. .BSRetrive select, .BSRetrive span {
  69. margin-right: 0;
  70. margin-left: 10px;
  71. float: right;
  72. }
  73. .BSRetrive span {
  74. margin-top: 5px;
  75. }
  76. `;
  77.  
  78. document.head.appendChild(style);
  79. };
  80.  
  81. BSRetrive.setup = function () {
  82. var anchor = $('h2');
  83.  
  84. if (!anchor || anchor.textContent.trim() !== 'Order Keys') return;
  85.  
  86. var BSContainer = document.createElement('div');
  87.  
  88. BSContainer.className = 'BSRetrive';
  89. BSContainer.innerHTML = `
  90. <textarea></textarea>
  91. <div>
  92. <button class="BSButtonReveal">Reveal</button>
  93. <button class="BSButtonRetrieve">Retrieve</button>
  94. <button class="BSButtonCopy">Copy</button>
  95. <button class="BSButtonReset">Reset</button>
  96. <label><input type="checkbox" class="BSCheckboxTitle">Include Game Title</label>
  97. <label><input type="checkbox" class="BSCheckboxJoin">Join Keys</label>
  98. <select class="BSSelectTo"></select>
  99. <span>to</span>
  100. <select class="BSSelectFrom"></select>
  101. </div>
  102. `;
  103.  
  104. anchor.parentNode.insertBefore(BSContainer, anchor);
  105.  
  106. $('.BSButtonReveal').addEventListener('click', () => {
  107. let keys = this.selector('.key-container a[ng-click^="redeemSerial"]');
  108.  
  109. if (keys) {
  110. for (let key of keys) {
  111. if (!key.closest('.ng-hide')) key.click();
  112. }
  113. } else msg.alert('Empty search, please select the correct options');
  114. });
  115.  
  116. $('.BSButtonRetrieve').addEventListener('click', () => {
  117. let containers = this.selector('.key-container');
  118.  
  119. if (containers) {
  120. let keys = [],
  121. includeTitle = $('.BSCheckboxTitle').checked,
  122. separator = $('.BSCheckboxJoin').checked ? ',' : "\n"
  123.  
  124. for (let container of containers) {
  125. let key = container.querySelector('input');
  126.  
  127. if (!key) continue;
  128. keys.push(
  129. includeTitle ?
  130. container.previousElementSibling.textContent + ', ' + key.value :
  131. key.value
  132. );
  133. }
  134.  
  135. $('.BSRetrive textarea').textContent = keys.join(separator);
  136. } else msg.alert('Empty search, please select the correct options');
  137. });
  138.  
  139. $('.BSButtonCopy').addEventListener('click', () => {
  140. $('.BSRetrive textarea').select();
  141. document.execCommand('copy');
  142. });
  143.  
  144. $('.BSButtonReset').addEventListener('click', () => {
  145. $('.BSRetrive textarea').textContent = '';
  146. });
  147.  
  148. this.baseElements = [document];
  149. var blocks = $$('hr ~ div > div:not(.ng-hide)'),
  150. selectFrom = $('.BSSelectFrom');
  151.  
  152. selectFrom.appendChild(new Option('All', 0));
  153.  
  154. for (let block of blocks) {
  155. let option,
  156. bundle = block.querySelector('h3'),
  157. tiers = Array.from(block.querySelectorAll('h4'));
  158.  
  159. if (tiers.length > 1) { //bundles (multiple tiers)
  160. for (let tier of tiers) {
  161. selectFrom.appendChild(new Option(
  162. bundle.textContent + ' ' + tier.textContent,
  163. this.baseElements.push(tier.parentNode) - 1
  164. ));
  165. }
  166. } else if (bundle) { //bundles (single tier)
  167. selectFrom.appendChild(new Option(
  168. bundle.textContent,
  169. this.baseElements.push(bundle.nextElementSibling) - 1
  170. ));
  171. } else { //individual games
  172. selectFrom.appendChild(new Option(
  173. block.querySelector('.title').textContent,
  174. this.baseElements.push(block) - 1
  175. ));
  176. }
  177. }
  178.  
  179. $('.BSSelectTo').innerHTML = selectFrom.innerHTML;
  180. };
  181.  
  182. BSRetrive.selector = function (selector) {
  183. var results = [],
  184. from = parseInt($('.BSSelectFrom').value),
  185. to = parseInt($('.BSSelectTo').value);
  186.  
  187. if (Number.isInteger(from) && Number.isInteger(to)) {
  188. if (from === 0 && to > 0) from = 1;
  189. if (from > 0 && to === 0) to = this.baseElements.length - 1;
  190.  
  191. for (var index = Math.min(from, to); index <= Math.max(from, to); index++) {
  192. let node = this.baseElements[index], result;
  193.  
  194. if (node) result = Array.from(node.querySelectorAll(selector));
  195. if (result) results = results.concat(result);
  196. }
  197. }
  198. return results;
  199. };
  200.  
  201. var msg = {
  202. box: null,
  203. init() {
  204. var style = document.createElement('style');
  205.  
  206. style.type = 'text/css';
  207. style.innerHTML = `
  208. .BSRetrive_msg {
  209. display: none;
  210. position: fixed;
  211. top: 50%;
  212. left: 50%;
  213. transform: translate(-50%, -50%);
  214. padding: 10px 20px;
  215. border: 1px solid #424242;
  216. background-color: rgb(32, 32, 32);
  217. color: #FFF;
  218. font-size: larger;
  219. }
  220. .BSRetrive_msg-show {
  221. display: block;
  222. }
  223. `;
  224. document.head.appendChild(style);
  225.  
  226. var BSRetrive_msg = document.createElement('div');
  227.  
  228. BSRetrive_msg.classList.add('BSRetrive_msg');
  229. document.body.appendChild(BSRetrive_msg);
  230. this.box = BSRetrive_msg;
  231. },
  232. alert(text) {
  233. this.box.textContent = text;
  234. this.box.classList.add('BSRetrive_msg-show');
  235. setTimeout(this.hide.bind(this), 3000);
  236. },
  237. hide() {
  238. this.box.classList.remove('BSRetrive_msg-show');
  239. }
  240. };
  241.  
  242. msg.init();
  243.  
  244. BSRetrive.init();
  245.  
  246. new MutationObserver(mutations => {
  247. for (let mutation of mutations) {
  248. if (!mutation.removedNodes.length) continue;
  249. if (mutation.removedNodes[0].id === 'loading-bar-spinner') BSRetrive.setup();
  250. }
  251. }).observe(document.body, {childList: true});
  252.  
  253. })();