共获取{{orderCounts}}订单,正在获取第{{currentOrder}}个订单
成功{{successOrderCount}}订单,失败{{errorOrderCount}}订单
`
const first = document.body.firstChild;//得到页面的第一个元素
document.body.insertBefore(wrap, first);
/**
* 加载CSS
* @param url
*/
function loadStyle(url) {
const link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
const head = document.getElementsByTagName('head')[0];
head.appendChild(link);
}
/**
* 加载JS
* @param url
* @param callback
*/
function loadScript(url, callback) {
const script = document.createElement("script");
script.type = "text/javascript";
if (typeof (callback) != "undefined") {
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState === "loaded" || script.readyState === "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function () {
callback();
};
}
}
script.src = url;
document.body.appendChild(script);
}
/**
* 主程序
*/
function start() {
new Vue({
el: '#app-1',
data() {
return {
loading: false,
table: false,
gridData: [],
allGame: {},
storeKey: true,
duration: 300,
currentOrder: 0,
orderCounts: 1,
successOrderCount: 0,
errorOrderCount: 0
}
},
methods: {
getOrders() {
return new Promise((resolve, reject) => {
$.ajax({
url: 'https://www.humblebundle.com/home/purchases?hmb_source=navbar',
success: rs => {
const doc = new DOMParser().parseFromString(rs, 'text/html');
const data = doc.querySelector('#user-home-json-data').innerText;
console.log(data);
resolve(JSON.parse(data));
},
error: e => {
reject(e);
}
})
})
},
getGameInfo(gameId) {
return new Promise((resolve, reject) => {
$.ajax({
url: API + gameId,
type: 'GET',
data: {all_tpkds: true},
success: rs => {
// console.log(rs);
resolve(rs);
},
error: e => {
reject(gameId);
}
})
})
},
sleep(time) {
return new Promise(resolve => {
setTimeout(() => {
resolve('ok');
}, time)
})
},
markGame() {
document.querySelectorAll('.entity-title').forEach(item => {
let name = item.innerText;
if (item.getAttribute('title')) {
name = item.getAttribute('title').toLowerCase();
}
if (Object.prototype.hasOwnProperty.call(this.allGame, `game_${name}`.toLowerCase())) {
// console.log('发现已购买过的游戏:', name);
item.style.background = 'green';
item.style.color = 'white';
}
})
},
watchHTML() {
const target = document.querySelector('body');
console.log(this.allGame);
const observer = new MutationObserver((mutations) => {
console.log('html change!');
this.markGame();
});
const config = {childList: true, subtree: true};
observer.observe(target, config);
// observer.disconnect();
}
},
mounted() {
this.allGame = GM_getValue("allGames");
this.storeKey = GM_getValue("storeKey");
GM_registerMenuCommand("更新已购买游戏", async () => {
// 选择是否存储KEY
await this.$confirm('是否需要存储KEY?', '确认信息', {
confirmButtonText: '存储',
cancelButtonText: '不存储'
}).then(() => {
console.log('store key: yes');
this.storeKey = true;
}).catch(action => {
console.log('store key: no');
this.storeKey = false;
});
GM_setValue("storeKey", this.storeKey);
console.log(`store key: ok, your choice is ${this.storeKey}`);
this.$message({
type: 'info',
message: `你的选择是${this.storeKey ? '' : '不'}存储Key`
});
// 获取订单信息
const orders = await this.getOrders().catch(err => {
this.$message.error('所有订单获取失败,请检查账号是否登陆!');
return
})
if (orders) {
const country = orders['userOptions']['selectedCountry'];
// this.$message(`你的账号区域为:${country}`);
const games = orders['gamekeys'];
console.log(`订单获取成功,共获得共获取${games.length}个订单!`)
this.$message({
message: `获取订单成功,共获取${games.length}个订单!`,
type: 'success'
});
// 遍历每个订单,获取游戏信息
this.loading = true;
this.orderCounts = games.length;
let allGames = {}
for (let i = 0; i < games.length; i++) {
let game = games[i];
const rs = await this.getGameInfo(game).catch(err => {
this.$message.error(`订单获取失败!`)
return
});
// 判断请求是否成功
if (rs) {
// 判断响应是否有效
try {
this.successOrderCount++;
const spent = rs['amount_spent'] + rs['currency'];
const time = rs['created'];
const type = rs['product']['category'];
if (type === 'storefront') {
const name = rs['tpkd_dict']['all_tpks'][0]['human_name'].toLowerCase();
const isExpired = rs['tpkd_dict']['all_tpks'][0]['is_expired']
const isGift = rs['tpkd_dict']['all_tpks'][0]['is_gift']
const keyType = rs['tpkd_dict']['all_tpks'][0]['key_type_human_name']
let key = '';
if (this.storeKey) {
key = rs['tpkd_dict']['all_tpks'][0]['redeemed_key_val']
}
console.log(`${game}信息获取成功,游戏为:${name}`)
allGames['game_' + name] = {isExpired, isGift, keyType, key, spent, time};
} else {
console.warn(`${game}, type: ${type}, continue!`);
}
} catch (e) {
this.errorOrderCount++;
console.error(`响应无效,${game}信息获取失败!`);
}
} else {
this.errorOrderCount++;
console.error(`请求失败,${game}信息获取失败!`);
}
this.currentOrder = i + 1;
await this.sleep(this.duration);
}
this.loading = false;
console.log('allGame:', allGames);
this.$message({
message: `共获取${Object.keys(allGames).length}个商店类型游戏!`,
type: 'success'
});
GM_setValue("allGames", allGames);
} else {
console.error(`获取所有订单失败!`)
}
}, "H");
GM_registerMenuCommand("显示所有已购买的商店游戏", () => {
this.gridData = [];
const games = GM_getValue("allGames");
if (!games) {
this.$message.error('请先点击上方按钮,更新游戏库存!');
return;
}
this.allGame = games;
console.log(games);
Object.keys(games).forEach(item => {
this.gridData.push({
name: item.substr(5),
isExpired: games[item].isExpired,
isGift: games[item].isGift,
key: games[item].key,
keyType: games[item].keyType,
time: games[item].time,
spent: games[item].spent,
})
})
console.log(this.gridData);
this.table = true;
}, "S");
console.log('allGame', this.allGame);
if (this.allGame) {
this.markGame();
this.watchHTML();
}
}
})
}
let vueLoaded = false;
loadStyle('https://unpkg.com/element-ui/lib/theme-chalk/index.css');
loadScript('https://unpkg.com/vue/dist/vue.js', () => {
vueLoaded = true
});
loadScript('https://unpkg.com/element-ui/lib/index.js', () => {
const timer = setInterval(() => {
if (vueLoaded) {
clearInterval(timer);
start();
}
}, 200)
});
})();