// ==UserScript==
// @name AuTo Redeem Steamkey
// @namespace HCLonely
// @author HCLonely
// @description 复制网页中的Steamkey后自动激活,3.0+版本为Beta版
// @supportURL https://blog.hclonely.com/posts/71381355/
// @homepage https://blog.hclonely.com/posts/71381355/
// @iconURL https://blog.hclonely.com/img/avatar.jpg
// @include *://*/*
// @exclude *store.steampowered.com/widget/*
// @exclude *googleads*
// @version 3.0.25
// @grant GM_setClipboard
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @run-at document-idle
// @require https://greasyfork.org/scripts/388035-$jQuery/code/$jQuery.js?version=736625
// @require https://greasyfork.org/scripts/389177-static/code/static.js?version=736626
// @require https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js
// @connect *
// @compatible chrome 没有测试其他浏览器的兼容性
// ==/UserScript==
(function() {
'use strict';
try{
hclonelyProgress+=" \nAuTo Redeem Steamkey:脚本开始加载...";
try{
if (typeof $jQuery != "function") throw 'error';
}catch(e){
GM_xmlhttpRequest({
method:'GET',
url:'https://greasyfork.org/scripts/388035-$jQuery/code/$jQuery.js?version=729328',
onload:data=>{
if(data.status==200){
eval(data.responseText);
}else{
console.error('AuTo Redeem Steamkey: \n资源加载失败:"https://greasyfork.org/scripts/388035-$jQuery/code/$jQuery.js?version=729328"');
hclonelyProgress+=" \nAuTo Redeem Steamkey: \n资源加载失败:\"https://greasyfork.org/scripts/388035-$jQuery/code/$jQuery.js?version=729328\"";
}
}
});
}
try{
if (Object.prototype.toString.call(arsStatic) != '[object Object]') throw 'error';
}catch(e){
GM_xmlhttpRequest({
method:'GET',
url:'https://greasyfork.org/scripts/389177-static/code/static.js?version=729329',
onload:data=>{
if(data.status==200){
eval(data.responseText);
}else{
console.error('AuTo Redeem Steamkey: \n资源加载失败:"https://greasyfork.org/scripts/389177-static/code/static.js?version=729329"');
hclonelyProgress+=" \nAuTo Redeem Steamkey: \n资源加载失败:\"https://greasyfork.org/scripts/389177-static/code/static.js?version=729329\"";
}
}
});
}
try{
if (typeof swal != "function") throw 'error';
}catch(e){
GM_xmlhttpRequest({
method:'GET',
url:'https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js',
onload:data=>{
if(data.status==200){
eval(data.responseText);
}else{
console.error('AuTo Redeem Steamkey: \n资源加载失败:"https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js"');
hclonelyProgress+=" \nAuTo Redeem Steamkey: \n资源加载失败:\"https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js\"";
}
}
});
}
try{
const url = window.location.href;
const defaultSetting={
newTab:false,
copyListen:true,
selectListen:true,
clickListen:true,
allKeyListen:false,
asf:false,
asfProtocol:'http',
asfHost:'127.0.0.1',
asfPort:1242,
asfPassword:'',
asfBot:'',
}
let sessionID="";
try{
sessionID=g_sessionID;
}catch(e){
sessionID="";
}
if(Object.prototype.toString.call(GM_getValue("setting")) != '[object Object]') GM_setValue("setting",defaultSetting);
const asfCommands=$jQuery(arsStatic.html[0])[0];
if(GM_getValue("setting").selectListen){
//选中激活功能
const iconSize = 24;
const translationTestSize = 16;
let icon = $jQuery(`<div class='icon-div' title='激活'><img src="${arsStatic.icon}" href="javascript:void(0)" class="icon-img"></div>`)[0];
// 添加激活图标到 DOM
document.documentElement.appendChild(icon);
// 鼠标事件:防止选中的文本消失
document.addEventListener('mousedown', function (e) {
if (e.target == icon || (e.target.parentNode && e.target.parentNode == icon) || (e.target.parentNode.parentNode && e.target.parentNode.parentNode == icon)) {// 点击了激活图标
e.preventDefault();
}
});
// 选中变化事件:当点击已经选中的文本的时候,隐藏激活图标和激活面板(此时浏览器动作是:选中的文本已经取消选中了)
document.addEventListener("selectionchange", ()=> {
if (!window.getSelection().toString().trim()) {
icon.style.display = 'none';
}
});
// 鼠标事件:防止选中的文本消失;显示、隐藏激活图标
document.addEventListener('mouseup', function (e) {
if (e.target == icon || (e.target.parentNode && e.target.parentNode == icon) || (e.target.parentNode.parentNode && e.target.parentNode.parentNode == icon)) {// 点击了激活图标
e.preventDefault();
return;
}
let text = window.getSelection().toString().trim();
let productKey = window.getSelection().toString().trim() || e.target.value;
if (/[\d\w]{5}(\-[\d\w]{5}){2}/.test(productKey) && text && icon.style.display == 'none') {
icon.style.top = e.pageY + 12 + 'px';
icon.style.left = e.pageX + 18 + 'px';
icon.style.display = 'block';
} else if (!text) {
icon.style.display = 'none';
}
});
// 激活图标点击事件
icon.addEventListener('click', function (e) {
let productKey = window.getSelection().toString().trim() || e.target.value;
registerkey(productKey);
});
}
//复制激活功能
if (!/https?:\/\/store\.steampowered\.com\/account\/registerkey[\w\W]{0,}/.test(url)&&GM_getValue("setting").copyListen){//非激活页面
let activateProduct = function(e) {
let productKey = window.getSelection().toString().trim() || e.target.value;
if (/^([\w\W]*)?([\d\w]{5}(\-[\d\w]{5}){2}(\r||,||,)?){1,}/.test(productKey)) {
if(!$jQuery("div.swal-overlay").hasClass("swal-overlay--show-modal")){
swal({
title:'检测到神秘key,是否激活?',
icon: 'success',
buttons:{
confirm:'激活',
cancel:'取消',
},
}).then((value) => {
if(value) registerkey(productKey);
});
}
}else if(/^\!addlicense.*[\d]+$/gi.test(productKey)){
if(Object.prototype.toString.call(GM_getValue("setting")) === '[object Object]'&&GM_getValue("setting").asf&&!$jQuery("div.swal-overlay").hasClass("swal-overlay--show-modal")){
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'检测到您复制了以下ASF指令,是否执行?',
text:productKey,
buttons:{
confirm:'执行',
cancel:'取消',
},
}).then((value)=>{
if(value) asfRedeem(productKey);
});
}
}
};
window.addEventListener("copy", activateProduct, false);
}
//激活页面自动激活
const selecter=url.includes("/account/registerkey")?"":".hclonely ";
const autoDivideNum = 9;
const waitingSeconds = 20;
const ajaxTimeout = 15;
let keyCount = 0;
let recvCount = 0;
let timer;
let allUnusedKeys = [];
const failureDetail = {
14: '无效激活码',
15: '重复激活',
53: '次数上限',
13: '地区限制',
9: '已拥有',
24: '缺少主游戏',
36: '需要PS3?',
50: '这是充值码',
};
const myTexts = {
fail: '失败',
success: '成功',
network: '网络错误或超时',
line: '——',
nothing: '',
others: '其他错误',
unknown: '未知错误',
redeeming: '激活中',
waiting: '等待中',
showUnusedKey: '显示未使用的Key',
hideUnusedKey: '隐藏未使用的Key',
};
const unusedKeyReasons = [
'次数上限',
'地区限制',
'已拥有',
'缺少主游戏',
'其他错误',
'未知错误',
'网络错误或超时',
];
function redeemKey(key) {
GM_xmlhttpRequest({
url: 'https://store.steampowered.com/account/ajaxregisterkey/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
Origin: 'https://store.steampowered.com',
Referer: 'https://store.steampowered.com/account/registerkey'
},
data:`product_key=${key}&sessionid=${sessionID}`,
method: 'POST',
responseType: 'json',
timeout: 1000 * ajaxTimeout,
onloadstart:function(){
if (jQuery(selecter+'table').is(':hidden')) {
jQuery(selecter+'table').fadeIn();
}
},
onload: function(response){
if(response.status==200&&response.response){
let data=response.response;
if (data.success == 1) {
tableUpdateKey(key, myTexts.success, myTexts.line,
data.purchase_receipt_info.line_items[0].packageid,
data.purchase_receipt_info.line_items[0].line_item_description);
return;
} else if (data.purchase_result_details !== undefined && data.purchase_receipt_info) {
if (!data.purchase_receipt_info.line_items[0]) {
tableUpdateKey(key, myTexts.fail,
failureDetail[data.purchase_result_details] ? failureDetail[data.purchase_result_details] : myTexts.others,
0, myTexts.nothing);
} else {
tableUpdateKey(key, myTexts.fail,
failureDetail[data.purchase_result_details] ? failureDetail[data.purchase_result_details] : myTexts.others,
data.purchase_receipt_info.line_items[0].packageid,
data.purchase_receipt_info.line_items[0].line_item_description);
}
return;
}
tableUpdateKey(key, myTexts.fail, myTexts.nothing, 0, myTexts.nothing);
}else{
tableUpdateKey(key, myTexts.fail, myTexts.network, 0, myTexts.nothing);
return;
}
},
});
}
function setUnusedKeys(key, success, reason, subId, subName) {
if (success && allUnusedKeys.includes(key)) {
var listObject;
allUnusedKeys = allUnusedKeys.filter(function(keyItem){
return keyItem != key;
});
$jQuery(selecter+'li').map((i,e)=>{
if($jQuery(e).html().includes(key)) {
listObject.remove();
}
});
} else if (!success && !allUnusedKeys.includes(key) && unusedKeyReasons.includes(reason)) {
listObject = $jQuery('<li></li>');
listObject.html(key + ' ( ' + reason +
(subId != 0 ? (': <code>' + subId + '</code> ' + subName) : '') +
' )');
$jQuery('#unusedKeys').append(listObject);
allUnusedKeys.push(key);
}
}
function tableInsertKey(key) {
keyCount++;
let row = $jQuery('<tr></tr>');
// number
row.append('<td class="nobr">' + keyCount + '</td>');
//key
row.append('<td class="nobr"><code>' + key + '</code></td>');
//redeeming...
row.append('<td colspan="3">' + myTexts.redeeming + '...</td>');
$jQuery(selecter+'tbody').prepend(row);
}
function tableWaitKey(key) {
keyCount++;
let row = $jQuery('<tr></tr>');
// number
row.append('<td class="nobr">' + keyCount + '</td>');
//key
row.append('<td class="nobr"><code>' + key + '</code></td>');
//waiting...
row.append('<td colspan="3">' + myTexts.waiting +
' (' + waitingSeconds + '秒)...</td>');
$jQuery(selecter+'tbody').prepend(row);
}
function tableUpdateKey(key, result, detail, subId, subName) {
setUnusedKeys(key, result === myTexts.success, detail, subId, subName);
recvCount++;
if (!selecter&&recvCount == keyCount) {
$jQuery('#buttonRedeem').fadeIn();
$jQuery('#inputKey').removeAttr('disabled');
}
var rowObjects = $jQuery(selecter+'tr');
for (let i = 1; i < rowObjects.length; i++) {
let rowElement = rowObjects[i];
let rowObject = $jQuery(rowElement);
if (rowObject.children()[1].innerHTML.includes(key)&&rowObject.children()[2].innerHTML.includes(myTexts.redeeming)) {
rowObject.children()[2].remove();
// result
if (result == myTexts.fail) rowObject.append('<td class="nobr" style="color:red">' + result + '</td>');
else rowObject.append('<td class="nobr" style="color:green">' + result + '</td>');
// detail
rowObject.append('<td class="nobr">' + detail + '</td>');
// sub
if (subId === 0) {
rowObject.append('<td>——</td>');
} else {
rowObject.append('<td><code>' + subId + '</code> <a href="https://steamdb.info/sub/' +
subId + '/" target="_blank">' + subName + '</a></td>');
}
break;
}
}
}
function startTimer() {
timer = setInterval(function() {
let flag = false;
let nowKey = 0;
let rowObjects = $jQuery(selecter+'tr');
for (let i = rowObjects.length - 1; i >= 1; i--) {
let rowElement = rowObjects[i];
let rowObject = $jQuery(rowElement);
if (rowObject.children()[2].innerHTML.includes(myTexts.waiting)) {
nowKey++;
if (nowKey <= autoDivideNum) {
let key = rowObject.children()[1].innerHTML.substring(6);
key = key.substring(0, key.indexOf('</code>'));
rowObject.children()[2].innerHTML = '<td colspan="3">' + myTexts.redeeming + '...</td>';
redeemKey(key);
} else {
flag = true;
break;
}
}
}
if (!flag) {
clearInterval(timer);
}
}, 1000 * waitingSeconds);
}
function redeem(keys){
if (keys.length <= 0) {
return;
}
if(!selecter){
$jQuery('#buttonRedeem').hide();
$jQuery('#inputKey').attr('disabled', 'disabled');
}
let nowKey = 0;
keys.forEach(function (key) {
nowKey++;
if (nowKey <= autoDivideNum) {
tableInsertKey(key);
redeemKey(key);
} else {
tableWaitKey(key);
}
});
if (nowKey > autoDivideNum) {
startTimer();
}
}
function redeemKeys(key) {
let keys = key||getKeysByRE($jQuery('#inputKey').val().trim());
redeem(keys);
}
function toggleUnusedKeyArea() {
if(!selecter){
if ($jQuery('#unusedKeyArea').is(':hidden')) {
$jQuery('#unusedKeyArea').show();
} else {
$jQuery('#unusedKeyArea').hide();
}
}
}
function setting(){
let setting=Object.prototype.toString.call(GM_getValue("setting")) === '[object Object]'?GM_getValue("setting"):defaultSetting;
let div=$jQuery(`
<div id="hclonely-asf">
<input type="checkbox" name="newTab" ${setting.newTab?'checked=checked':''} title="开启ASF激活后此功能无效"/><span title="开启ASF激活后此功能无效">新标签页激活</span><br/>
<input type="checkbox" name="copyListen" ${setting.copyListen?'checked=checked':''} title="复制key时询问是否激活"/><span title="复制key时询问是否激活">开启复制捕捉</span>
<input type="checkbox" name="selectListen" ${setting.selectListen?'checked=checked':''} title="选中key时显示激活图标"/><span title="选中key时显示激活图标">开启选中捕捉</span>
<input type="checkbox" name="clickListen" ${setting.clickListen?'checked=checked':''} title="点击key时添加激活链接"/><span title="点击key时添加激活链接">开启点击捕捉</span><br/>
<input type="checkbox" name="allKeyListen" ${setting.allKeyListen?'checked=checked':''} title="匹配页面内所有符合steam key格式的内容"/><span title="匹配页面内所有符合steam key格式的内容">捕捉页面内所有key</span>
<div class="swal-title">ASF IPC设置</div>
<span>ASF IPC协议</span><input type="text" name="asfProtocol" value='${setting.asfProtocol}' placeholder="http或https,默认为http"/><br/>
<span>ASF IPC地址</span><input type="text" name="asfHost" value='${setting.asfHost}' placeholder="ip地址或域名,默认为127.0.0.1"/><br/>
<span>ASF IPC端口</span><input type="text" name="asfPort" value='${setting.asfPort}' placeholder="默认1242"/><br/>
<span>ASF IPC密码</span><input type="text" name="asfPassword" value='${setting.asfPassword}' placeholder="ASF IPC密码"/><br/>
<span>ASF Bot名字</span><input type="text" name="asfBot" value='${setting.asfBot}' placeholder="ASF Bot name,可留空"/><br/>
<input type="checkbox" name="asf" ${setting.asf?'checked=checked':''} title="此功能默认关闭新标签页激活"/><span title="此功能默认关闭新标签页激活">开启ASF激活</span>
</div>`)[0];
swal({
closeOnClickOutside: false,
className:'asf-class',
title:'全局设置',
content: div,
buttons:{
confirm:'保存',
cancel:'取消',
},
})
.then((value) => {
if(value){
let setting={};
let allSetting=$jQuery("#hclonely-asf input").map(function(){
setting[$jQuery(this).attr("name")]=this.value==="on"?this.checked:this.value;
});
GM_setValue("setting",setting);
swal({
closeOnClickOutside: false,
icon:"success",
title:'保存成功!',
text:'刷新页面后生效!',
buttons:{
confirm:'确定',
},
});
}
});
}
function asfSend(c=''){
if(Object.prototype.toString.call(GM_getValue("setting")) === '[object Object]'&&GM_getValue("setting").asf){
swal({
closeOnClickOutside: false,
className:'swal-user',
text:'请在下方输入要执行的ASF指令:',
content: 'input',
buttons:{
'test':'连接测试',
'redeem':'激活key',
'pause':'暂停挂卡',
'resume':'恢复挂卡',
'2fa':'获取令牌',
'more':'更多ASF指令',
confirm:'确定',
cancel:'取消',
},
}).then((value) => {
switch(value){
case 'redeem':
swalRedeem();
break;
case 'pause':
case 'resume':
case '2fa':
asfRedeem("!"+value);
break;
case 'test':
asfTest();
break;
case 'more':
swal({
closeOnClickOutside: false,
className:'swal-user',
text:'ASF指令',
content: asfCommands,
buttons:{
confirm:'返回',
cancel:'关闭',
},
}).then((value)=>{
if(value) asfSend();
});
$jQuery('table.hclonely button.swal-button').click(function(){
let setting=Object.prototype.toString.call(GM_getValue("setting")) === '[object Object]'?GM_getValue("setting"):defaultSetting;
let command=setting.asfBot?$jQuery(this).parent().next().text().trim().replace(/\<Bots\>/gim,setting.asfBot):$jQuery(this).parent().next().text().trim();
asfSend(command);
});
break;
case null:
break;
default:
if(!$jQuery('.swal-content__input').val()){
swal({
closeOnClickOutside: false,
title:'ASF指令不能为空!',
icon:'warning',
buttons:{
confirm:'确定',
},
}).then(()=>{asfSend(c)});
}else{
let v=value||$jQuery('.swal-content__input').val();
if(v) asfRedeem(v);
}
break;
break;
}
});
if(c) $jQuery('.swal-content__input').val("!"+c);
}else{
swal({
closeOnClickOutside: false,
className:'swal-user',
icon:"warning",
title:'此功能需要在设置中配置ASF IPC并开启ASF功能!',
buttons:{
confirm:'确定',
},
});
}
}
function swalRedeem(){
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'请输入要激活的key:',
content:$jQuery(`<textarea id='keyText' class='asf-output'></textarea>`)[0],
buttons:{
confirm:'激活',
cancel:'返回'
}
}).then((value)=>{
if(value){
let key=getKeysByRE($jQuery('#keyText').val());
if(key.length>0) asfRedeem("!redeem "+(GM_getValue("setting").asfBot?(GM_getValue("setting").asfBot+" "):"")+key.join(','));
else swal({
closeOnClickOutside: false,
title:'steam key不能为空!',
icon:'error',
buttons:{
confirm:'返回',
cancel:'关闭'
}
}).then((value)=>{
if(value) swalRedeem();
});
}else{
asfSend();
}
});
}
function asfTest(){
let setting=GM_getValue("setting")||{};
if(setting.asf){
swal({
closeOnClickOutside: false,
title:'ASF连接测试',
text:'正在尝试连接 "'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/Api/Command/\"",
buttons:{
confirm:'确定',
},
});
GM_xmlhttpRequest({
method:"POST",
url:setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/Api/Command/",
data:`{\"Command\":\"!stats\"}`,
responseType:"json",
headers:{
"accept": "application/json",
"Content-Type": "application/json",
"Authentication": setting.asfPassword,
"Host": setting.asfHost+":"+setting.asfPort,
"Origin": setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort,
"Referer": setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/page/commands"
},
onload:function(data){
if(data.status==200){
if(data.response.Success==true&&data.response.Message=="OK"&&data.response.Result){
swal({
closeOnClickOutside: false,
title:'ASF连接成功!',
icon:'success',
text:'连接地址 "'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/Api/Command/\" \n返回内容 \""+data.response.Result.trim()+"\"",
buttons:{
confirm:'确定',
},
});
}else if(data.response.Message){
swal({
closeOnClickOutside: false,
title:'ASF连接成功?',
icon:'info',
text:'连接地址 "'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/Api/Command/\" \n返回内容 \""+data.response.Message.trim()+"\"",
buttons:{
confirm:'确定',
},
});
}else{
swal({
closeOnClickOutside: false,
title:'ASF连接失败!',
icon:'error',
text:'连接地址 "'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/Api/Command/\" \n返回内容 \""+data.responseText+"\"",
buttons:{
confirm:'确定',
},
});
}
}else{
swal({
closeOnClickOutside: false,
title:'ASF连接失败:'+data.status,
icon:'error',
text:'连接地址 "'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+'/Api/Command/\"',
buttons:{
confirm:'确定',
},
});
}
}
})
}else{
swal({
closeOnClickOutside: false,
title:'请先在设置中开启ASF功能',
icon:'warning',
buttons:{
confirm:'确定',
},
});
}
}
function showHistory(){
let history=GM_getValue("history");
if(Array.isArray(history)){
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'上次激活记录:',
content:$jQuery(history[0])[0],
buttons:{
confirm:'确定',
},
});
if(history[1]) $jQuery(".swal-content textarea").val(history[1]);
}else{
swal({
closeOnClickOutside: false,
title:'没有操作记录!',
icon:"error",
buttons:{
cancel:'关闭',
},
});
}
}
function showSwitchKey(){
swal({
closeOnClickOutside: false,
title:'请选择要转换成什么格式:',
buttons:{
confirm:"确定",
cancel:'关闭'
},
content:$jQuery(`<div class='switch-key'><div class='switch-key-left'><p>key</p><p>key</p><p>key</p><input name='keyType' type='radio' value='1'/></div><div class='switch-key-right'><p> </p><p>key,key,key</p><p> </p><input name='keyType' type='radio' value='2'/></div></div>`)[0],
}).then((value)=>{
if(value){
if($jQuery('input:radio:checked').val()){
showSwitchArea($jQuery('input:radio:checked').val());
}else{
swal({
closeOnClickOutside: false,
title:'请选择要将key转换成什么格式!',
icon:'warning',
}).then(showSwitchKey);
}
}
});
function showSwitchArea(type){
swal({
closeOnClickOutside: false,
title:'请输入要转换的key:',
content:$jQuery(`<textarea style='width: 80%;height: 100px;'></textarea>`)[0],
buttons:{
confirm:'转换',
'back':'返回',
cancel:'关闭',
}
}).then((value)=>{
if(value==='back'){
showSwitchKey(type);
}else if(value){
switchKey($jQuery('.swal-content textarea').val(),type);
}
});
}
function switchKey(key,type){
switch(type){
case '1':
showKey(getKeysByRE(key).join("\n"),type);
break;
case '2':
showKey(getKeysByRE(key).join(','),type);
break;
default:
break;
}
}
function showKey(key,type){
swal({
closeOnClickOutside: false,
icon:'success',
title:'转换成功!',
content:$jQuery(`<textarea style='width: 80%;height: 100px;' value='${key}' readonly='readonly'>${key}</textarea>`)[0],
buttons:{
confirm:'返回',
cancel:'关闭',
}
}).then((value)=>{
if(value){
showSwitchArea(type);
}
});
$jQuery('.swal-content textarea').click(function(){this.select()});
}
$jQuery('.switch-key div').map(function(){
$jQuery(this).click(function(){
$jQuery(this).find('input')[0].click();
});
});
}
function getKeysByRE(text) {
text = text.trim().toUpperCase();
let reg = new RegExp('([0-9,A-Z]{5}-){2,4}[0-9,A-Z]{5}', 'g');
let keys = [];
let result = void 0;
while (result = reg.exec(text)) {
keys.push(result[0]);
}
return keys;
}
function registerkey(key){
let setting=GM_getValue("setting");
let keys=getKeysByRE(key);
if(setting.asf) asfRedeem("!redeem "+(setting.asfBot?(setting.asfBot+" "):"")+keys.join(","));
else if(setting.newTab) window.open("https://store.steampowered.com/account/registerkey?key=" + keys.join(","), "_blank");
else webRedeem(keys);
}
function asfRedeem(command){
let setting=GM_getValue("setting");
let textarea=document.createElement("textarea");
textarea.setAttribute("class","asf-output");
textarea.setAttribute("readonly","readonly");
let btn=/\!redeem/gim.test(command)?{confirm:'提取未使用key',cancel:'关闭'}:{confirm:'确定'};
swal({
closeOnClickOutside: false,
className:'swal-user',
text:'正在执行ASF指令:'+command,
content: textarea,
buttons:btn,
}).then((v)=>{
if(/\!redeem/gim.test(command)){
let value="";
if($jQuery(".swal-content textarea").length>0){
value=$jQuery(".swal-content textarea").val();
}
GM_setValue("history",[$jQuery(".swal-content").html(),value]);
if(v){
let unUseKey=$jQuery(".swal-content textarea").val().split(/[(\r\n)\r\n]+/).map(function(e){
if(/未使用/gim.test(e)){
return e;
}
}).join(',');
GM_setClipboard(arr(getKeysByRE(unUseKey)).join(","));
swal({title:'复制成功!',icon:"success"});
}
}
});
GM_xmlhttpRequest({
method:"POST",
url:setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/Api/Command",
data:`{\"Command\":\"${command}\"}`,
responseType:"json",
headers:{
"accept": "application/json",
"Content-Type": "application/json",
"Authentication": setting.asfPassword,
"Host": setting.asfHost+":"+setting.asfPort,
"Origin": setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort,
"Referer": setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/page/commands"
},
onload:function(data){
console.log(data);
console.log(command);
if(data.status==200){
if(data.response.Success==true&&data.response.Message=="OK"&&data.response.Result){
textarea.value+=data.response.Result.trim()+" \n";
}else if(data.response.Message){
textarea.value+=data.response.Message.trim()+" \n";
}else{
textarea.value+=data.responseText;
}
}else{
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'执行ASF指令('+command+')失败!请检查ASF配置是否正确!',
text:data.text||data.status,
icon: 'error',
buttons:{
confirm:'关闭',
},
});
}
}
})
}
function webRedeem(key){
let div=$jQuery(`<div id="registerkey_examples_text"><div class="notice_box_content" id="unusedKeyArea"> <b>未使用的Key:</b><br><div><ol id="unusedKeys" align="left"></ol></div></div><div class="table-responsive table-condensed"><table class="table table-hover hclonely"><caption><h2>激活记录</h2></caption><thead><th>No.</th><th>Key</th><th>结果</th><th>详情</th><th>Sub</th></thead><tbody></tbody></table></div><br></div>`)[0];
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'正在获取sessionID...',
buttons:{
confirm:'关闭',
},
});
if(sessionID){
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'正在激活steam key...',
content: div,
buttons:{
confirm:'提取未使用key',
cancel:'关闭',
},
}).then((v)=>{
let value="";
if($jQuery(".swal-content textarea").length>0){
value=$jQuery(".swal-content textarea").val();
}
GM_setValue("history",[$jQuery(".swal-content").html(),value]);
if(v){
GM_setClipboard(arr(getKeysByRE($jQuery('#unusedKeys').text())).join(","));
swal({title:'复制成功!',icon:"success"});
}
});
redeemKeys(key);
}else{
GM_xmlhttpRequest({
method:"GET",
url:"https://store.steampowered.com/account/registerkey",
onload:function(data){
if(data.finalUrl.includes("login")){
swal({
closeOnClickOutside: false,
icon:"warning",
title:'请先登录steam!',
buttons:{
confirm:'登录',
cancel:'关闭',
},
}).then((value)=>{
if(value) window.open("https://store.steampowered.com/login/","_blank");
});
}else{
if(data.status==200){
let session_id = data.responseText.match(/g_sessionID = \"(.+?)\";/);
sessionID = session_id === null ? null : session_id[1];
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'正在激活steam key...',
content: div,
buttons:{
confirm:'提取未使用key',
cancel:'关闭',
},
}).then((v)=>{
let value="";
if($jQuery(".swal-content textarea").length>0){
value=$jQuery(".swal-content textarea").val();
}
GM_setValue("history",[$jQuery(".swal-content").html(),value]);
if(v){
GM_setClipboard(getKeysByRE($jQuery('#unusedKeys').text()).join(","));
swal({title:'复制成功!',icon:"success"});
}
});
redeemKeys(key);
}else{
swal({
closeOnClickOutside: false,
className:'swal-user',
title:'获取sessionID失败!',
icon: 'error',
buttons:{
confirm:'关闭',
},
});
}
}
}
})
}
}
function redeemSub(e){
let subText=e||document.getElementById("gameSub").value;
if(subText){
let ownedPackages = {};
$jQuery( '.account_table a' ).each( function( i, el ){
let match = el.href.match( /javascript:RemoveFreeLicense\( ([0-9]+), '/ );
if( match !== null ){
ownedPackages[ +match[ 1 ] ] = true;
}
} );
let freePackages =subText.match(/[\d]{2,}/g);
let i = 0,
loaded = 0,
packae = 0,
total = freePackages.length,
modal = swal( '正在执行…','请等待所有请求完成。 忽略所有错误,让它完成。' );
for( ; i < total; i++ ){
packae = freePackages[ i ];
if( ownedPackages[ packae ] ){
loaded++;
continue;
}
$jQuery.post('//store.steampowered.com/checkout/addfreelicense',{
action: 'add_to_cart',
sessionid: g_sessionID,
subid: packae
}).always(function(){
loaded++;
if( loaded >= total ){
if(url.includes("licenses")){
window.open("https://store.steampowered.com/account/licenses/","_self");
}else{
swal("全部激活完成,是否前往账户页面查看结果?", {
buttons: {
cancel: "取消",
"确定": true,
},
})
.then((value) => {
if(value) window.open("https://store.steampowered.com/account/licenses/","_blank");
});
}
}else{
modal = swal( '正在激活…','进度:' + loaded + '/' + total + '.' );
}
});
}
}
}
function cc(){
swal({
closeOnClickOutside: false,
icon:'info',
title:`正在获取当前国家/地区...`,
})
$jQuery.ajax({
url:"//store.steampowered.com/cart/",
type:"get",
success:function(data){
if(data.match(/id\=\"usercountrycurrency_trigger\"[\w\W]*?\>[w\W]*?\<\/a/gim)){
let c=data.match(/id\=\"usercountrycurrency_trigger\"[\w\W]*?\>[w\W]*?\<\/a/gim)[0].replace(/id\=\"usercountrycurrency_trigger\"[\w\W]*?\>|\<\/a/g,"");
let thisC=data.match(/id\=\"usercountrycurrency\"[\w\W]*?value=\".*?\"/gim)[0].match(/value=\".*?\"/gim)[0].replace(/value=\"|\"/g,"");
let div=data.match(/\<div class=\"currency_change_options\"\>[\w\W]*?\<p/gim)[0].replace(/[\s]*?\<p/gim,"")+"</div>";
//$jQuery("body").append(`<div id="nowCountry" class="ellipsis" data-country="${thisC}" style="font-size:20px;">转换商店和钱包 当前国家/地区:${c}</div><div style="padding:20px">${div}</div></div>`);
swal({
closeOnClickOutside: false,
title:`当前国家/地区:${c}`,
content:$jQuery(`<div>${div}</div>`)[0],
})
$jQuery(".currency_change_option").click(function(){
changeCountry($jQuery(this).attr("data-country"));
});
}else{
swal("需要挂相应地区的梯子!","","warning");
}
},
error:()=>{
swal("获取当前国家/地区失败!","","error");
}
});
}
function changeCountry(country){
swal({
closeOnClickOutside: false,
icon:'info',
title:`正在更换国家/地区...`,
})
$jQuery.ajax({
url:"//store.steampowered.com/account/setcountry",
type:"post",
data:{
sessionid:g_sessionID,
"cc":country
},
complete:function(){
$jQuery.ajax({
url:"//store.steampowered.com/cart/",
type:"get",
success:function(data){
let c=data.match(/id\=\"usercountrycurrency_trigger\"[\w\W]*?\>[w\W]*?\<\/a/gim)[0].replace(/id\=\"usercountrycurrency_trigger\"[\w\W]*?\>|\<\/a/g,"");
let thisC=data.match(/id\=\"usercountrycurrency\"[\w\W]*?value=\".*?\"/gim)[0].match(/value=\".*?\"/gim)[0].replace(/value=\"|\"/g,"");
let div=data.match(/\<div class=\"currency_change_options\"\>[\w\W]*?\<p/gim)[0].replace(/[\s]*?\<p/gim,"")+"</div>";
if(thisC===country){
swal("更换成功!","","success").then(()=>{
swal({
closeOnClickOutside: false,
title:`当前国家/地区:${c}`,
content:$jQuery(`<div>${div}</div>`)[0],
})
$jQuery(".currency_change_option").click(function(){
changeCountry($jQuery(this).attr("data-country"));
});
});
}else{
swal("更换失败!","","error");
}
},
error:()=>{
swal("获取当前国家/地区失败!","","error");
}
});
}
});
}
function arr(arr) {
return [...new Set(arr)];
}
if (/^https?:\/\/store\.steampowered\.com\/account\/registerkey*/.test(url)){
$jQuery('#registerkey_examples_text').html(
'<div class="notice_box_content" id="unusedKeyArea" style="display: none">' +
'<b>未使用的Key:</b><a tabindex="300" class="btnv6_blue_hoverfade btn_medium" id="copyUnuseKey"><span>提取未使用key</span></a><br>'+
'<div><ol id="unusedKeys">' +
'</ol></div>' +
'</div>' +
'<div class="table-responsive table-condensed">' +
'<table class="table table-hover" style="display: none">' +
'<caption><h2>激活记录</h2></caption><thead><th>No.</th><th>Key</th>' +
'<th>结果</th><th>详情</th><th>Sub</th></thead><tbody></tbody>' +
'</table></div><br>');
$jQuery('#copyUnuseKey').click(()=>{
GM_setClipboard(arr(getKeysByRE($jQuery('#unusedKeys').text())).join(","));
swal({title:'复制成功!',icon:"success"});
});
$jQuery('.registerkey_input_box_text').parent().css("float","none");
$jQuery('.registerkey_input_box_text').parent().append('<textarea class="form-control" rows="3"' +
' id="inputKey" placeholder="支持批量激活,可以把整个网页文字复制过来 ' +
'若一次激活的Key的数量超过9个则会自动分批激活(等待20秒) ' +
'激活多个SUB时每个SUB之间用英文逗号隔开 ' +
'激活礼物卡或钱包充值码功能目前属于测试功,且不支持批量激活"' +
' style="margin: 3px 0px 0px; width: 525px; height: 102px;"></textarea><br>');
/^https?:\/\/store\.steampowered\.com\/account\/registerkey\?key\=[\w\W]+/.test(url)&&(document.getElementById("inputKey").value=url.replace(/https?:\/\/store\.steampowered\.com\/account\/registerkey\?key\=/i,""));
$jQuery('.registerkey_input_box_text').hide();
$jQuery('#purchase_confirm_ssa').hide();
$jQuery('#register_btn').parent().css("margin","10px 0")
$jQuery('#register_btn').parent().append('<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
' id="redeemKey"><span>激活key</span></a>' + ' ' +
'<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
' id="redeemSub"><span>激活sub</span></a>' + ' ' +
'<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
' id="redeemCode"><span>激活礼物卡或钱包充值码</span></a>' + ' ' +
'<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
' id="changeCountry"><span>更换国家/地区</span></a>' + ' ');
$jQuery('#register_btn').remove();
/^https?:\/\/store\.steampowered\.com\/account\/registerkey\?key\=[\w\W]+/.test(url)&&(redeem(getKeysByRE(url.replace(/https?:\/\/store\.steampowered\.com\/account\/registerkey\?key\=/i,"").trim())));
$jQuery('#redeemKey').click(()=>{redeemKeys()});
$jQuery('#redeemSub').click(redeemSubs);
$jQuery('#changeCountry').click(cc);
function redeemSubs(){
redeemSub($jQuery('#inputKey').val().trim());
}
arsStatic.redeemCode();
toggleUnusedKeyArea();
}else if(/https?:\/\/steamdb\.info\/freepackages\//.test(url)){//steamdb.info点击自动跳转到激活页面
let activateConsole = function(e) {
let sub=[];
$("#freepackages span:visible").map(function(){
sub.push($(this).attr("data-subid"));
});
let freePackages=sub.join(",");
let setting=GM_getValue("setting");
window.open("https://store.steampowered.com/account/licenses/?sub=" + freePackages, "_self");
//if(setting.asf) asfRedeem("!addlicense "+(setting.asfBot||"asf")+" "+freePackages);
//else window.open("https://store.steampowered.com/account/licenses/?sub=" + freePackages, "_self");
};
let fp=setInterval(()=>{
if(document.getElementById("freepackages")){
document.getElementById("freepackages").onclick=activateConsole;
clearInterval(fp);
}
},1000);
}else if (/https?:\/\/store\.steampowered\.com\/account\/licenses\/(\?sub\=[\w\W]{0,})?/.test(url)){//自动添加sub
$jQuery('.pageheader').parent().append('<div style="float: left;";>' +
'<textarea class="registerkey_input_box_text" rows="1"' + 'name="product_key"' +
' id="gameSub" placeholder="输入SUB,多个SUB之间用英文逗号连接"' + 'value=""' + 'color:#fff;' +
' style="margin: 3px 0px 0px; width: 400px; height: 15px;background-color:#102634; padding: 6px 18px 6px 18px; font-weight:bold; color:#fff;"></textarea>' +
'   ' + '</div>' + '<a tabindex="300" class="btnv6_blue_hoverfade btn_medium"' +
' style="width: 95px; height: 30px;"' +
' id="buttonSUB"><span>激活SUB</span></a>'+ '<a tabindex="300" class="btnv6_blue_hoverfade btn_medium"' +
' style="width: 125px; height: 30px;margin-left:5px"' +
' id="changeCountry"><span>更改国家/地区</span></a>');
$jQuery('#buttonSUB').click(()=>{redeemSub()});
$jQuery('#changeCountry').click(cc);
if (/https?:\/\/store\.steampowered\.com\/account\/licenses\/\?sub\=([\d]{1,},){1,}/.test(url)){
setTimeout(()=>{redeemSub(url)},2000);
}
}else if(GM_getValue("setting").clickListen){//点击添加链接
function mouseClick($,e) {
let $i = $("<span/>").text("Steam Key");
let x = e.pageX,
y = e.pageY;
$i.css({"z-index" : 9999999999999999999,"top" : y - 20,"left" : x,"position" : "absolute","font-weight" : "bold","color" : "#ff6651"});
$("body").append($i);
$i.animate({"top" : y - 180,"opacity" : 0}, 1500, ()=>{$i.remove()});
};
let htmlEl;
if(window.document.body){
window.document.body.onclick = function(event){
htmlEl = event.target;//鼠标每经过一个元素,就把该元素赋值给变量htmlEl
if($jQuery(htmlEl).parents('.swal-overlay').length==0&&htmlEl.tagName!=='A' && htmlEl.tagName!=='BUTTON' && htmlEl.getAttribute("type")!=='button' && htmlEl.tagName!=='TEXTAREA' && htmlEl.getAttribute("type")!=='text'){
if(($jQuery(htmlEl).children().length==0||!/([0-9,A-Z]{5}-){2,4}[0-9,A-Z]{5}/gim.test($jQuery.makeArray($jQuery(htmlEl).children().map(function(){
return $jQuery(this).text();
})).join("")))&&/([0-9,A-Z]{5}-){2,4}[0-9,A-Z]{5}/gim.test($jQuery(htmlEl).text())){
mouseClick($jQuery,event);
arr($jQuery(htmlEl).text().match(/[\w\d]{5}(-[\w\d]{5}){2}/gim)).map(function(e){
$jQuery(htmlEl).html($jQuery(htmlEl).html().replace(new RegExp(e,'gi'),`<a class="redee-key" href='javascript:void(0)' target="_self" key='${e}'>${e}</a>`));
});
$jQuery('.redee-key').click(function(){
registerkey($jQuery(this).attr("key"),1);
});
}
}
}
}
}
if(GM_getValue("setting").allKeyListen){//激活页面内所有key
function addBtn(){
let div = document.createElement("div");
div.setAttribute("id", "keyDiv");
div.setAttribute("style", "position:fixed;left:5px;bottom:5px");
let btn=document.createElement("button");
btn.setAttribute("id", "allKey");
btn.setAttribute("key", "");
btn.setAttribute("style", "display:none;z-index:9999");
btn.setAttribute("class", "btn btn-default");
btn.innerText="激活本页面所有key(共0个)";
btn.onclick=function(){
let setting=GM_getValue("setting");
let keys=getKeysByRE($jQuery(this).attr("key"));
if(setting.asf) asfRedeem("!redeem "+setting.asfBot+" "+keys.join(","));
else if(setting.newTab) window.open("https://store.steampowered.com/account/registerkey?key=" + keys.join(","), "_blank");
else webRedeem(keys);
}
$jQuery('body').append(div);
div.appendChild(btn);
return btn;
}
function redeemAllKey(){
let len=0;
let keyList="";
let hasKey=[];
let btn=addBtn();
setInterval(function(){
let allSteamKey=arr(getKeysByRE($jQuery('body').text()))||[];
len=allSteamKey.length;
if(len>0){
hasKey.push(...allSteamKey);
hasKey=arr(hasKey);
keyList=hasKey.join(",");
if($jQuery(btn).attr("key")!=keyList){
$jQuery(btn).attr("key",keyList);
$jQuery(btn).text("激活本页面所有key(共" + hasKey.length + "个)");
$jQuery(btn).show();
}
}else if(document.getElementById('allKey')&&(document.getElementById('allKey').style.display==="block")){
$jQuery(btn).hide();
$jQuery(btn).text("激活本页面所有key(共0个)");
}
},1000);
}
redeemAllKey();
}
GM_addStyle(arsStatic.css);
GM_registerMenuCommand("⚙设置",setting);
GM_registerMenuCommand("执行ASF指令",asfSend);
GM_registerMenuCommand("查看上次激活记录",showHistory);
GM_registerMenuCommand("Key格式转换",showSwitchKey);
GM_registerMenuCommand("新版使用说明",()=>{window.open('https://keylol.com/t344489-1-1','_blank')});
hclonelyProgress+=" \nAuTo Redeem Steamkey:脚本加载完成!";
}catch(e){
//if(!/The provided markup is invalid XML/gim.test(e.stack))
swal("AuTo Redeem Steamkey脚本执行出错","脚本运行进度: \n"+hclonelyProgress+" \n错误详情: \n"+e.stack,'error');
console.log(e.stack);
}finally{
console.log(hclonelyProgress);
}
}catch(e){
console.error("AuTo Redeemer Steamkey脚本执行出错: \n资源加载失败:https://greasyfork.org/scripts/388035-$jQuery/code/$jQuery.js?version=729328");
}
}());