Greasy Fork 还支持 简体中文。

AuTo Redeemer Steamkey

复制网页中的Steamkey后自动激活,3.0+版本为Beta版

Verze ze dne 24. 08. 2019. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name        AuTo Redeemer Steamkey
// @namespace   HCLonely
// @author      HCLonely
// @description 复制网页中的Steamkey后自动激活,3.0+版本为Beta版
// @supportURL  https://steamcn.com/t344489-1-1
// @include     *://*/*
// @exclude     *store.steampowered.com/widget/*
// @version     3.0.12
// @grant       GM_setClipboard
// @grant       GM_addStyle
// @grant       GM_registerMenuCommand
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_xmlhttpRequest
// @run-at      document-end
// @require     https://greasyfork.org/scripts/376437-hclonely-function/code/HCLonely_function.js?version=660229
// @require     https://greasyfork.org/scripts/388035-$jQuery/code/$jQuery.js?version=721233
// @require     https://greasyfork.org/scripts/389177-static/code/static.js?version=727966
// @require     https://cdn.bootcss.com/sweetalert/2.1.2/sweetalert.min.js
// @connect     *
// ==/UserScript==

(function() {
    'use strict';

    try{

        const url = window.location.href;

        const defaultSetting={
            newTab:false,
            copyListen:true,
            selectListen:true,
            clickListen:true,
            allKeyListen:true,
            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 = document.createElement('div');
            const style = '' +
                  'position:absolute;' +
                  'width:32px;' +
                  'height:32px;' +
                  'margin:0px!important;' +
                  '';
            icon.innerHTML = '' +
                '<img src="'+arsStatic.icon+'" href="javascript:void(0)" style="' + style + '">'
            '';
            icon.setAttribute('style', '' +
                              'width:32px!important;' +
                              'height:32px!important;' +
                              'display:none!important;' +
                              'background:#fff!important;' +
                              'border-radius:16px!important;' +
                              'box-shadow:4px 4px 8px #888!important;' +
                              'position:absolute!important;' +
                              'z-index:2147483647!important;' +
                              'cursor:pointer;'+
                              '');
            icon.setAttribute("title","激活");

            // 添加激活图标到 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 (/^([\w\W]*)?([\d\w]{5}(\-[\d\w]{5}){2}(\r||,||,)?){1,}/.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).innerHTML.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=document.createElement("div");
            div.setAttribute("id","hclonely-asf");
            div.innerHTML=`
<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>`;

            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':
                        case 'pause':
                        case 'resume':
                        case '2fa':
                            asfSend(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 asfTest(){
            let setting=GM_getValue("setting")||{};
            if(setting.asf){
                swal({
                    closeOnClickOutside: false,
                    title:'ASF连接测试',
                    text:'正在尝试连接 `'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/api/command/!stats`",
                    buttons:{
                        confirm:'确定',
                    },
                });
                GM_xmlhttpRequest({
                    method:"POST",
                    url:setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/api/command/!stats",
                    responseType:"json",
                    headers:{
                        "Authentication": setting.asfPassword,
                        "Content-Length": 0,
                        "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/!stats` \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/!stats` \n返回内容 `"+data.response.Message.trim()+"`",
                                    buttons:{
                                        confirm:'确定',
                                    },
                                });
                            }else{
                                swal({
                                    closeOnClickOutside: false,
                                    title:'ASF连接失败!',
                                    icon:'error',
                                    text:'连接地址 `'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+"/api/command/!stats` \n返回内容 `"+data.responseText+"`",
                                    buttons:{
                                        confirm:'确定',
                                    },
                                });
                            }
                        }else{
                            swal({
                                closeOnClickOutside: false,
                                title:'ASF连接失败:'+data.status,
                                icon:'error',
                                text:'连接地址 `'+setting.asfProtocol+"://"+setting.asfHost+":"+setting.asfPort+'/api/command/!stats`',
                                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>&nbsp;</p><p>key,key,key</p><p>&nbsp;</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+" "+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/"+command.replace(/ /g,"%20"),
                responseType:"json",
                headers:{
                    "Authentication": setting.asfPassword,
                    "Content-Length": 0,
                    "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){
                            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指令失败!请检查ASF配置是否正确!',
                            text:command,
                            icon: 'error',
                            buttons:{
                                confirm:'关闭',
                            },
                        });
                    }
                }
            })
        }
        function webRedeem(key){
            let div=document.createElement("div");
            div.setAttribute("id","registerkey_examples_text");
            div.innerHTML=`
<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>`;
            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;">转换商店和钱包&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当前国家/地区:${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="支持批量激活,可以把整个网页文字复制过来&#10;' +
                                                                  '若一次激活的Key的数量超过9个则会自动分批激活(等待20秒)&#10;' +
                                                                  '激活多个SUB时每个SUB之间用英文逗号隔开&#10;' +
                                                                  '激活礼物卡或钱包充值码功能目前属于测试功,且不支持批量激活"' +
                                                                  ' 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>' + ' &nbsp;&nbsp;' +
                                                    '<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
                                                    ' id="redeemSub"><span>激活sub</span></a>' + ' &nbsp;&nbsp;' +
                                                    '<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
                                                    ' id="redeemCode"><span>激活礼物卡或钱包充值码</span></a>' + ' &nbsp;&nbsp;' +
                                                    '<a tabindex="300" class="btnv6_blue_hoverfade btn_medium" style="margin-left:0"' +
                                                    ' id="changeCountry"><span>更换国家/地区</span></a>' + ' &nbsp;&nbsp;');
            $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>' +
                                                  ' &nbsp ' + '</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;"' +
                                                  ' 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://steamcn.com/t344489-1-1','_blank')});
    }catch(e){
        swal("AuTo Redeemer Steamkey脚本执行出错:",e.stack,'error');
    }

}());