您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Displays a text area with game titles and keys so you can copy them out easily.
当前为
// ==UserScript== // @name Humble Bundle Keys Backup // @namespace Lex@GreasyFork // @version 0.1 // @description Displays a text area with game titles and keys so you can copy them out easily. // @author Lex // @match https://www.humblebundle.com/downloads* // @grant none // ==/UserScript== (function() { 'use strict'; function formatGames(games) { // Ignore games which do not have keys revealed //games = games.filter(e => e.key); // Format the output as tab-separated games = games.map(e => (e.title+"\t"+e.key).trim()); return games.join("\n"); } function createNotify(bundle, message) { const areaName = "ktt-notify"; let notify = bundle.querySelector("."+areaName); if (!notify) { notify = document.createElement("div"); notify.className = areaName; bundle.append(notify); } notify.innerHTML = message; return notify; } function createArea() { const area = document.createElement("textarea"); area.className = "key-text-area"; area.style.width = "100%"; area.setAttribute('readonly', true); return area; } // Updates an area if it needs updating, adjusting the height to fit the contents function updateArea(area, updateStr) { if (area.value != updateStr) { area.value = updateStr; // Adjust the height so all the contents are visible area.style.height = ""; area.style.height = area.scrollHeight + 20 + "px"; } } // Returns array of the games in the target bundle function getGames(bundle) { let games = []; bundle.querySelectorAll(".key-redeemer").forEach(div => { let game = {}; game.title = div.querySelector(".heading-text h4").innerText; const keyfield = div.querySelector(".keyfield"); game.key = keyfield.title; if (game.key == "Reveal your Steam key") { game.key = ""; game.revealed = false; } else { game.revealed = true; } game.isGift = keyfield.classList.contains("redeemed-gift"); game.isKey = keyfield.classList.contains("redeemed"); games.push(game); }); return games; } function handlePage() { document.querySelectorAll(".key-container.wrapper").forEach(bundle => { const gameCount = document.querySelectorAll(".keyfield").length; const revealedCount = document.querySelectorAll(".redeemed,.redeemed-gift").length; const color = gameCount == revealedCount ? "" : "tomato"; let notifyHtml = `Found ${gameCount} keyfields. <span style="background:${color}">${revealedCount} are revealed.</span>`; if (gameCount != revealedCount) { notifyHtml += " Are some keys not revealed?"; } createNotify(bundle, notifyHtml); const area = createArea(); bundle.append(area); const games = getGames(bundle); updateArea(area, formatGames(games)); }); } function waitForLoad(query, callback) { if (document.querySelector(query)) { callback(); } else { setTimeout(waitForLoad.bind(null, query, callback), 100); } } waitForLoad(".key-redeemer", handlePage); })();