您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
复制网页中的Steamkey后自动激活,3.0+版本为Beta版
// ==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/[email protected]/dist/jquery.min.js // @require https://gf.qytechs.cn/scripts/431728-ars-static/code/ARS-Static.js?version=966071 // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert.min.js // @connect * // @compatible chrome 没有测试其他浏览器的兼容性 // ==/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(`<div class='icon-div' title='激活'><img src="${arsStatic.icon}" href="javascript:void(0)" class="icon-img"></div>`)[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( '<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="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) 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('<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) { // 点击添加链接 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 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('<li></li>') listObject.html(key + ' ( ' + reason + (subId !== 0 ? (': <code>' + subId + '</code> ' + subName) : '') + ' )') $jQuery('#unusedKeys').append(listObject) allUnusedKeys.push(key) } } function tableInsertKey (key) { keyCount++ const row = $jQuery('<tr></tr>') row.append('<td class="nobr">' + keyCount + '</td>') row.append('<td class="nobr"><code>' + key + '</code></td>') row.append('<td colspan="3">' + myTexts.redeeming + '...</td>') $jQuery(selecter + 'tbody').prepend(row) } function tableWaitKey (key) { keyCount++ const row = $jQuery('<tr></tr>') row.append('<td class="nobr">' + keyCount + '</td>') row.append('<td class="nobr"><code>' + key + '</code></td>') 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++) { 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('<td class="nobr" style="color:red">' + result + '</td>') else rowObject.append('<td class="nobr" style="color:green">' + result + '</td>') rowObject.append('<td class="nobr">' + detail + '</td>') 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 () { 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('</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) { 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(` <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) { 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(/<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 { 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('<textarea id=\'keyText\' class=\'asf-output\'></textarea>')[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('<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() 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('<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) { 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(/<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) { 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(/<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 redeemSubs () { redeemSub($jQuery('#inputKey').val().trim()) } function mouseClick ($, e) { const $i = $('<span/>').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)] } }($))
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址