// ==UserScript== // @name AuTo Redeem Steamkey // @namespace HCLonely // @author HCLonely // @description 复制网页中的Steamkey后自动激活,3.0+版本为Beta版 // @version Test-3.1.0 // @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* // @grant GM_setClipboard // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @run-at document-idle // @require https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js // @require https://greasyfork.org/scripts/431728-ars-static/code/ARS-Static.js?version=966071 // @require https://cdn.jsdelivr.net/npm/sweetalert@2.1.2/dist/sweetalert.min.js // @connect * // @compatible chrome 没有测试其他浏览器的兼容性 // @downloadURL https://update.greasyfork.icu/scripts/36666/AuTo%20Redeem%20Steamkey.user.js // @updateURL https://update.greasyfork.icu/scripts/36666/AuTo%20Redeem%20Steamkey.meta.js // ==/UserScript== /* global g_sessionID, swal, arsStatic */ (function ($jQuery) { 'use strict' 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 // eslint-disable-line camelcase } catch (e) { sessionID = '' } if (Object.prototype.toString.call(GM_getValue('setting')) !== '[object Object]') GM_setValue('setting', defaultSetting) const asfCommands = $jQuery(arsStatic.html)[0] // 激活页面自动激活 const selecter = url.includes('/account/registerkey') ? '' : '.hclonely ' const autoDivideNum = 9 const waitingSeconds = 20 const ajaxTimeout = 15 let keyCount = 0 let recvCount = 0 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 = [ '次数上限', '地区限制', '已拥有', '缺少主游戏', '其他错误', '未知错误', '网络错误或超时' ] try { if (GM_getValue('setting').selectListen) { // 选中激活功能 const icon = $jQuery(`
`)[0] 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 } const text = window.getSelection().toString().trim() const 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) { const 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) { // 非激活页面 const activateProduct = function (e) { const 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) } if (/^https?:\/\/store\.steampowered\.com\/account\/registerkey*/.test(url)) { $jQuery('#registerkey_examples_text').html( '' + '
' + '' + '' + '' + '

') $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('
'); /^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('激活key' + '   ' + '激活sub' + '   ' + '更换国家/地区' + '   ') $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) toggleUnusedKeyArea() } else if (/https?:\/\/steamdb\.info\/freepackages\//.test(url)) { // steamdb.info点击自动跳转到激活页面 const activateConsole = function (e) { const sub = [] $('#freepackages span:visible').map(function () { sub.push($(this).attr('data-subid')) }) const freePackages = sub.join(',') // const 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"); } const 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('
' + '' + '   ' + '
' + '激活SUB' + '更改国家/地区') $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) { // 点击添加链接 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'), `${e}`)) }) $jQuery('.redee-key').click(function () { registerkey($jQuery(this).attr('key'), 1) }) } } } } } if (GM_getValue('setting').allKeyListen) { // 激活页面内所有key 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') }) } catch (e) { swal('AuTo Redeem Steamkey脚本执行出错,详情请查看控制台!', e.stack, 'error') console.error(e) } 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) { const 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) } } }) } 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('
  • ') listObject.html(key + ' ( ' + reason + (subId !== 0 ? (': ' + subId + ' ' + subName) : '') + ' )') $jQuery('#unusedKeys').append(listObject) allUnusedKeys.push(key) } } function tableInsertKey (key) { keyCount++ const row = $jQuery('') row.append('' + keyCount + '') row.append('' + key + '') row.append('' + myTexts.redeeming + '...') $jQuery(selecter + 'tbody').prepend(row) } function tableWaitKey (key) { keyCount++ const row = $jQuery('') row.append('' + keyCount + '') row.append('' + key + '') row.append('' + myTexts.waiting + ' (' + waitingSeconds + '秒)...') $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++) { const rowElement = rowObjects[i] const rowObject = $jQuery(rowElement) if (rowObject.children()[1].innerHTML.includes(key) && rowObject.children()[2].innerHTML.includes(myTexts.redeeming)) { rowObject.children()[2].remove() if (result === myTexts.fail) rowObject.append('' + result + '') else rowObject.append('' + result + '') rowObject.append('' + detail + '') if (subId === 0) { rowObject.append('——') } else { rowObject.append('' + subId + ' ' + subName + '') } break } } } function startTimer () { const timer = setInterval(function () { let flag = false let nowKey = 0 const rowObjects = $jQuery(selecter + 'tr') for (let i = rowObjects.length - 1; i >= 1; i--) { const rowElement = rowObjects[i] const 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('')) rowObject.children()[2].innerHTML = '' + myTexts.redeeming + '...' 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) { const 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 () { const setting = Object.prototype.toString.call(GM_getValue('setting')) === '[object Object]' ? GM_getValue('setting') : defaultSetting const div = $jQuery(`
    新标签页激活
    开启复制捕捉 开启选中捕捉 开启点击捕捉
    捕捉页面内所有key
    ASF IPC设置
    ASF IPC协议
    ASF IPC地址
    ASF IPC端口
    ASF IPC密码
    ASF Bot名字
    开启ASF激活
    `)[0] swal({ closeOnClickOutside: false, className: 'asf-class', title: '全局设置', content: div, buttons: { confirm: '保存', cancel: '取消' } }) .then((value) => { if (value) { const setting = {} $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 () { const setting = Object.prototype.toString.call(GM_getValue('setting')) === '[object Object]' ? GM_getValue('setting') : defaultSetting const command = setting.asfBot ? $jQuery(this).parent().next().text().trim().replace(//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 { const v = value || $jQuery('.swal-content__input').val() if (v) asfRedeem(v) } 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('')[0], buttons: { confirm: '激活', cancel: '返回' } }).then((value) => { if (value) { const 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 () { const 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 () { const 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('

    key

    key

    key

     

    key,key,key

     

    ')[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('')[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(``)[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() const reg = new RegExp('([0-9,A-Z]{5}-){2,4}[0-9,A-Z]{5}', 'g') const keys = [] let result while (result = reg.exec(text)) { // eslint-disable-line no-cond-assign keys.push(result[0]) } return keys } function registerkey (key) { const setting = GM_getValue('setting') const 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) { const setting = GM_getValue('setting') const textarea = document.createElement('textarea') textarea.setAttribute('class', 'asf-output') textarea.setAttribute('readonly', 'readonly') const 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) { const 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) { const div = $jQuery('
    未使用的Key:

      激活记录

      No.Key结果详情Sub

      ')[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) { const gSessionId = data.responseText.match(/g_sessionID = "(.+?)";/) sessionID = gSessionId === null ? null : gSessionId[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) { const subText = e || document.getElementById('gameSub').value if (subText) { const ownedPackages = {} $jQuery('.account_table a').each(function (i, el) { const match = el.href.match(/javascript:RemoveFreeLicense\( ([0-9]+), '/) if (match !== null) { ownedPackages[+match[1]] = true } }) const freePackages = subText.match(/[\d]{2,}/g) let i = 0 let loaded = 0 let packae = 0 const total = freePackages.length 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 { 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)) { const c = data.match(/id="usercountrycurrency_trigger"[\w\W]*?>[w\W]*?<\/a/gim)[0].replace(/id="usercountrycurrency_trigger"[\w\W]*?>|<\/a/g, '') // const thisC = data.match(/id="usercountrycurrency"[\w\W]*?value=".*?"/gim)[0].match(/value=".*?"/gim)[0].replace(/value="|"/g, '') const div = data.match(/
      [\w\W]*?

      ' // $jQuery("body").append(`

      转换商店和钱包     当前国家/地区:${c}
      ${div}
      `); swal({ closeOnClickOutside: false, title: `当前国家/地区:${c}`, content: $jQuery(`
      ${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) { const c = data.match(/id="usercountrycurrency_trigger"[\w\W]*?>[w\W]*?<\/a/gim)[0].replace(/id="usercountrycurrency_trigger"[\w\W]*?>|<\/a/g, '') const thisC = data.match(/id="usercountrycurrency"[\w\W]*?value=".*?"/gim)[0].match(/value=".*?"/gim)[0].replace(/value="|"/g, '') const div = data.match(/
      [\w\W]*?

      ' if (thisC === country) { swal('更换成功!', '', 'success').then(() => { swal({ closeOnClickOutside: false, title: `当前国家/地区:${c}`, content: $jQuery(`

      ${div}
      `)[0] }) $jQuery('.currency_change_option').click(function () { changeCountry($jQuery(this).attr('data-country')) }) }) } else { swal('更换失败!', '', 'error') } }, error: () => { swal('获取当前国家/地区失败!', '', 'error') } }) } }) } function redeemSubs () { redeemSub($jQuery('#inputKey').val().trim()) } function mouseClick ($, e) { const $i = $('').text('Steam Key') const x = e.pageX const 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() }) } function addBtn () { const div = document.createElement('div') div.setAttribute('id', 'keyDiv') div.setAttribute('style', 'position:fixed;left:5px;bottom:5px') const 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 () { const setting = GM_getValue('setting') const 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 = [] const btn = addBtn() setInterval(function () { const 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) } function arr (arr) { return [...new Set(arr)] } }($))