// ==UserScript==
// @name Humble Bundle Auto Redeem
// @namespace http://tampermonkey.net/
// @version 0.2
// @description HB download 页面刮key
// @author kumi
// @match https://www.humblebundle.com/downloads?key=*
// @icon https://humblebundle-a.akamaihd.net/static/hashed/46cf2ed85a0641bfdc052121786440c70da77d75.png
// @license MIT
// @downloadURL none
// ==/UserScript==
(async function () {
'use strict';
const request = async ({ url, method, body, headers }) => {
const res = await fetch(url, {
method: method || 'GET',
body: body || null,
headers
})
if (res.status !== 200) return {}
return res.json()
}
const getGameKey = async (gameItem) => {
let result
try {
result = await request({
url: 'https://www.humblebundle.com/humbler/redeemkey',
body: `keytype=${gameItem.machine_name}&key=${gameItem.gamekey}&keyindex=${gameItem.keyindex}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
method: 'POST'
})
} catch(e) {
result = {key: '请求失败'}
}
return result
}
const parentEle = document.querySelector('.js-subproduct-whitebox-holder')
const ele = document.createElement('div')
ele.innerHTML = ``
parentEle.insertBefore(ele, parentEle.firstElementChild)
ele.firstElementChild.onclick = async function() {
if(this.innerText !== '全部刮开') return
this.innerText = `正在刮key...`
const [, orderId] = location.href.match(/downloads\?key=(\w+)/) || []
const { tpkd_dict: { all_tpks } } = await request({
url: `https://www.humblebundle.com/api/v1/order/${orderId}?all_tpkds=true`,
})
const platformObj = all_tpks.reduce((obj, item, index) => {
if (!obj[item.key_type_human_name]) obj[item.key_type_human_name] = []
if(all_tpks.length - 1 === index) {
obj.temp.push(item)
obj.tpks.push(obj.temp)
return obj
}
if(obj.temp.length >= 4) {
obj.temp.push(item)
obj.tpks.push(obj.temp)
obj.temp = []
} else {
obj.temp.push(item)
}
return obj
}, {tpks: [], temp: []})
const { tpks } = platformObj
delete platformObj.tpks
delete platformObj.temp
let count = 0
for (let j = 0; j < tpks.length; j++) {
const gameArr = tpks[j]
const result = await Promise.all(gameArr.map(getGameKey))
result.forEach((item, index) => {
this.innerText = `${++count}/${all_tpks.length}`
const game = gameArr[index]
platformObj[game.key_type_human_name].push(`${game.human_name},${item.key}`)
})
}
const platform = Object.keys(platformObj)
const gameText = []
for (let i = 0; i < platform.length; i++) {
const keyType = platform[i]
gameText.push(keyType + '平台\n'+ platformObj[keyType].join('\n'))
}
ele.lastElementChild.value = gameText.join('\n\n')
}
})();