您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Displays a text area with game titles and keys so you can copy them out easily.
当前为
- // ==UserScript==
- // @name Fanatical Keys Backup
- // @namespace Lex@GreasyFork
- // @version 0.2
- // @description Displays a text area with game titles and keys so you can copy them out easily.
- // @author Lex
- // @match https://www.fanatical.com/en/orders/*
- // @grant none
- // ==/UserScript==
- (function() {
- 'use strict';
- // Formats games array to a string to be displayed
- // Games is an array [ [title, key], ... ]
- function formatGames(games) {
- // Ignore games which do not have keys revealed
- games = games.filter(e => e[1]);
- // Format the output as tab-separated
- games = games.map(e => e[0]+"\t"+e[1]);
- return games.join("\n");
- }
- function getGames(bundle) {
- let is = bundle.querySelectorAll(".order-item");
- return Array.prototype.map.call(is, i => {
- const gameTitleElement = i.getElementsByClassName("game-name");
- const gameTitle = gameTitleElement.length > 0 ? gameTitleElement[0].textContent.trim() : "";
- const keyElement = i.querySelector("[aria-label='reveal-key']");
- const gameKey = keyElement ? keyElement.value : "";
- return [gameTitle, gameKey];
- });
- }
- function revealAllKeys(bundle) {
- const revealButtons = document.querySelectorAll(".key-container button.btn-block");
- revealButtons.forEach(b => { b.click() });
- }
- function createRevealButton(bundle) {
- const notify = bundle.querySelector(".ktt-notify");
- let btn = document.createElement("button");
- btn.type = "button"; // no default behavior
- btn.innerText = "Reveal All Keys";
- btn.onclick = revealAllKeys.bind(btn, bundle);
- return btn;
- }
- // Adds a textarea to the bottom of the games listing with all the titles and keys
- function handleBundle(bundle) {
- const bundleName = bundle.querySelector("h5.my-4") ? bundle.querySelector("h5.my-4").textContent.trim() : "No Title";
- let games = getGames(bundle);
- const gameCount = games.length;
- const keyCount = games.filter(e => e[1]).length;
- const gameStr = formatGames(games);
- let notify = bundle.querySelector(".ktt-notify");
- if (!notify) {
- notify = document.createElement("div");
- notify.className = "ktt-notify";
- bundle.append(notify);
- if (gameCount != keyCount) {
- const btn = createRevealButton(bundle);
- notify.before(btn);
- }
- }
- const color = gameCount == keyCount ? "" : "red";
- let newInner = `Dumping keys for ${bundleName}: Found ${gameCount} items and <span style="background-color:${color}">${keyCount} keys</span>.`;
- if (gameCount != keyCount) {
- newInner += " Are some keys not revealed?";
- }
- if (notify.innerHTML != newInner) {
- notify.innerHTML = newInner;
- }
- let area = bundle.querySelector(".ktt");
- if (!area) {
- area = document.createElement("textarea");
- area.className = "ktt";
- area.style.width = "100%";
- area.setAttribute('readonly', true);
- bundle.append(area);
- }
- if (area.value != gameStr) {
- area.value = gameStr;
- // Adjust the height so all the contents are visible
- area.style.height = "";
- area.style.height = area.scrollHeight + 20 + "px";
- }
- }
- var loopCount = 0;
- function handleOrderPage() {
- // There can be more than one bundle in an order
- const bundles = document.querySelectorAll("hr.mb-4 ~ div");
- if (bundles.length > 0) {
- console.log(`Found ${bundles.length} bundle(s)`);
- bundles.forEach(handleBundle);
- setTimeout(handleOrderPage, 2000);
- } else {
- if (loopCount++ < 100) {
- setTimeout(handleOrderPage, 100);
- }
- }
- }
- handleOrderPage();
- })();