AuTo Redeemer Steamkey(自动激活Steamkey)

复制网页中的Steamkey后自动激活

当前为 2019-08-21 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        AuTo Redeemer Steamkey(自动激活Steamkey)
// @namespace   HCLonely
// @author      HCLonely
// @description 复制网页中的Steamkey后自动激活
// @supportURL  https://steamcn.com/t344489-1-1
// @include     *://*/*
// @exclude     *store.steampowered.com/widget/*
// @version     3.0.4 Beta
// @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-arshtml/code/arsHtml.js?version=726801
// @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,
            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(arsHtml[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="'+arsHtml[2]+'" 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>
<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(){
            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:{
                        'more':'更多ASF指令',
                        confirm:'确定',
                        cancel:'取消',
                    },
                }).then((value) => {
                    if(value==='more'){
                        swal({
                            closeOnClickOutside: false,
                            className:'swal-user',
                            text:'ASF指令',
                            content: asfCommands,
                            buttons:{
                                confirm:'返回',
                                cancel:'关闭',
                            },
                        }).then((value)=>{
                            if(value) asfSend();
                        });
                    }else if(value){
                        asfRedeem(value);
                    }
                });
            }else{
                swal({
                    closeOnClickOutside: false,
                    className:'swal-user',
                    icon:"warning",
                    title:'此功能需要在设置中配置ASF IPC并开启ASF功能!',
                    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(){
            $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){
            $jQuery.ajax({
                url:"//store.steampowered.com/account/setcountry",
                type:"post",
                data:{
                    sessionid:g_sessionID,
                    "cc":country
                },
                complete:function(data){
                    $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>";

                            $jQuery(".currency_change_option").click(function(){
                                changeCountry($jQuery(this).attr("data-country"));
                            });
                            if(thisC===country){
                                swal("更换成功!","","success").then(()=>{
                                    swal({
                                        closeOnClickOutside: false,
                                        title:`当前国家/地区:${c}`,
                                        content:$jQuery(`<div>${div}</div>`)[0],
                                    })
                                });
                            }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('#redeemCode').click(redeemCode);
            $jQuery('#changeCountry').click(cc);

            $jQuery(".block_content.checkout_content_box").append(arsHtml[1]);
            function DisplayPage( page ){
                $('error_display').innerHTML = '';
                $('error_display').style.display = 'none';

                switch ( page ){
                    case 'code':
                        $('wallet_code_form').style.display = '';
                        $('redeem_wallet_code_upsell_text').style.display = '';
                        $('address_form').style.display = 'none';
                        $('redeem_amount_form').style.display = 'none';
                        $('validate_btn').style.display = '';
                        $('validate_btn_in_progress').style.display = 'none';
                        $jQuery('#inputKey').val('');
                        break;

                    case 'address':
                        $('address_btn').style.display = '';
                        $('address_btn_in_progress').style.display = 'none';
                        $('wallet_code_form').style.display = 'none';
                        $('redeem_wallet_code_upsell_text').style.display = 'none';
                        $('main_content').style.backgroundImage = "url('')";
                        $('address_form').style.display = '';
                        $('redeem_amount_form').style.display = 'none';
                        break;

                    case 'redeem_amount':
                        $('redeem_btn').style.display = '';
                        $('redeem_btn_in_progress').style.display = 'none';
                        $('wallet_code_form').style.display = 'none';
                        $('redeem_wallet_code_upsell_text').style.display = 'none';
                        $('main_content').style.backgroundImage = "url('')";
                        $('address_form').style.display = 'none';
                        $('redeem_amount_form').style.display = '';
                        break;
                }
            }

            function UpdateStateSelection(){
                try{
                    if ( $('billing_country').value == 'US' ){
                        $('billing_state_text').style.display = 'none';
                        $('billing_state_select_dselect_container').style.display = 'block';
                    }else{
                        $('billing_state_text').style.display = 'block';
                        $('billing_state_select_dselect_container').style.display = 'none';
                    }
                }catch( e ){
                    ReportRedeemJSError( 'Failed in UpdateStateSelection()', e );
                }
            }

            function ReportRedeemJSError( message, e ){
                try{
                    if (typeof e == 'string')
                        e = new Error(e);

                    ReportError( '/public/javascript/redeemwalletcode.js?l=schinese', message, message+":\n\n  Exception: "+e.name+" - "+e.message+"\n" );
                } catch( e ){
                }
            }

            var g_bValidateWalletCodeCallRunning = false;
            function ValidateWalletCode(){
                if( g_bValidateWalletCodeCallRunning )
                    return;

                if ( $jQuery('#inputKey').val().trim() == '' ){
                    DisplayErrorMessage( '您必须输入钱包充值码来继续。' );
                }
                else{
                    try{
                        g_bValidateWalletCodeCallRunning = true;

                        $('validate_btn').style.display = 'none';
                        $('validate_btn_in_progress').style.display = '';

                        new Ajax.Request('https://store.steampowered.com/account/validatewalletcode/',{
                            method:'post',
                            parameters: {
                                'wallet_code' : $jQuery('#inputKey').val().trim(),
                                'sessionid' : g_sessionID
                            },
                            onSuccess: function(transport){
                                g_bValidateWalletCodeCallRunning = false;
                                if ( transport.responseText ){
                                    try {
                                        var result = transport.responseText.evalJSON(true);
                                    } catch ( e ) {
                                        // Failure
                                        OnValidateWalletCodeFailure( 2 );
                                    }
                                    // Success...
                                    if ( result.success == 1 && result.detail == 0 ){
                                        OnValidateWalletCodeSuccess( result );
                                        return;
                                    }
                                    else{
                                        OnValidateWalletCodeFailure( result.detail );
                                        return;
                                    }
                                }

                                OnValidateWalletCodeFailure( 0  );
                            },
                            onFailure: function(){
                                g_bValidateWalletCodeCallRunning = false;
                                OnValidateWalletCodeFailure( 0  );
                            }
                        });
                    }catch(e){
                        ReportRedeemJSError( 'Failed gathering form data and calling ValidateWalletCode', e );
                    }
                }
            }

            var g_sWalletCodeAmount;
            var g_sExchangedWalletCodeAmount;

            function OnValidateWalletCodeSuccess( result ){
                try{
                    $('error_display').innerHTML = '';
                    $('error_display').style.display = 'none';

                    g_sWalletCodeAmount = result.formattedcodeamount;
                    g_sExchangedWalletCodeAmount = g_sWalletCodeAmount;

                    UpdateRedeemForm( result );

                    if ( result.haswallet ){
                        if ( result.currency == result.wallet.currencycode ){
                            RedeemWalletCode();
                        }else{
                            CreateWalletAndCheckFunds( false );
                        }
                    }else{
                        DisplayPage( 'address' );
                        UpdateStateSelection();
                    }
                }catch( e ){
                    ReportRedeemJSError( 'Failed handling ValidateWalletCode success', e );
                }
            }

            function OnValidateWalletCodeFailure( detail ){
                try{
                    var sErrorMessage = '发生了一个意外错误。您的 Steam 钱包充值码目前无法被兑换。请在 30 分钟后重新兑换该充值码。如果您仍然遇到问题,请联系 <a href="https://help.steampowered.com/wizard/HelpWithWalletCode">Steam 客服</a>寻求进一步的帮助。';

                    switch ( detail ){
                        case 14:
                            sErrorMessage = '您输入的 Steam 钱包充值码无效。重新输入时请仔细核对字符。';
                            break;

                        case 15:
                            sErrorMessage = '您输入的 Steam 钱包充值码已被兑换。Steam 客服无法向您发放新的充值码。';
                            break;

                        case 58:
                            sErrorMessage = '您输入的 Steam 钱包充值码尚未被激活。请注意,充值码可能在购买几小时后才会由您的零售商完成激活。如果您仍然遇到问题,请联系充值码的卖家寻求进一步的帮助。';
                            break;

                        case 9:
                            sErrorMessage = '您输入的 Steam 钱包充值码已于先前兑换到您的帐户中了。';
                            break;

                        default:
                            sErrorMessage = '发生了一个意外错误。您的 Steam 钱包充值码目前无法被兑换。请在 30 分钟后重新兑换该充值码。如果您仍然遇到问题,请联系 <a href="https://help.steampowered.com/wizard/HelpWithWalletCode">Steam 客服</a>寻求进一步的帮助。';
                            break;
                    }

                    DisplayErrorMessage( sErrorMessage );
                    $('validate_btn').style.display = '';
                    $('validate_btn_in_progress').style.display = 'none';

                }catch (e){
                    ReportRedeemJSError( 'Failed handling ValidateWalletCode failure', e );
                }
            }

            function SubmitAddressForm(){
                var errorString = '';

                var rgBadFields = {
                    billing_address : false,
                    billing_city : false,
                    billing_state_text : false,
                    billing_postal_code : false,
                    billing_state_select_trigger : false
                }

                try{
                    if ( $( 'billing_address' ).value.length < 1 ){
                        errorString += '请输入您的账单地址。<br/>';
                        rgBadFields.billing_address = true;
                    }

                    if ( $( 'billing_city' ).value.length < 1 ){
                        errorString += '请输入您的账单城市。<br/>';
                        rgBadFields.billing_city = true;
                    }

                    if  ( $( 'billing_country' ).value == 'US' ){
                        if ( $('billing_state_select').value.length < 1 ){
                            errorString += '请输入一个州或省。<br/>';
                            rgBadFields.billing_state_select_trigger = true;
                        }
                    }

                    if ( $( 'billing_country' ).value == 'US' ){
                        if ( $( 'billing_postal_code' ).value.length < 5 ){
                            errorString += '请输入您所在地区的邮政编码。<br/>';
                            rgBadFields.billing_postal_code = true;
                        }
                    }else if ( $( 'billing_postal_code' ).value.length < 1 ){
                        errorString += '请输入您所在地区的邮政编码。<br/>';
                        rgBadFields.billing_postal_code = true;
                    }
                }catch(e){
                    ReportRedeemJSError( 'Failed validating address info form', e );
                }

                try{
                    for ( var key in rgBadFields ){
                        if ( rgBadFields[key] ){
                            ValidationMarkFieldBad( key );
                        }else{
                            ValidationMarkFieldOk( key );
                        }
                    }

                    if ( errorString != '' ){
                        var rgErrors = errorString.split( '<br/>' );
                        if ( rgErrors.length > 3 ){
                            errorString = '';
                            errorString = rgErrors[0] + '<br/>' + rgErrors[1] + '<br/>' + '并查看下面突出显示的更多错误。' + '<br/>';
                        }

                        DisplayErrorMessage( errorString );
                    }else{
                        $('error_display').innerHTML = '';
                        $('error_display').style.display = 'none';

                        CreateWalletAndCheckFunds( true );
                    }
                }catch(e){
                    ReportRedeemJSError( 'Failed showing error or submitting payment info form', e );
                }
            }

            var g_bCreateWalletAndCheckFundsRunning = false;
            function CreateWalletAndCheckFunds( bCreateFromAddress ){
                if( g_bCreateWalletAndCheckFundsRunning )
                    return;

                try{
                    g_bCreateWalletAndCheckFundsRunning = true;

                    $('address_btn').style.display = 'none';
                    $('address_btn_in_progress').style.display = '';

                    new Ajax.Request('https://store.steampowered.com/account/createwalletandcheckfunds/',{
                        method:'post',
                        parameters: {
                            'wallet_code' : $jQuery('#inputKey').val().trim(),
                            'CreateFromAddress' : bCreateFromAddress ? 1 : 0,
                            'Address' : $('billing_address').value,
                            'City' : $('billing_city').value,
                            'Country' : $('billing_country').value,
                            'State' : ($('billing_country').value == 'US' ? $('billing_state_select').value : $('billing_state_text').value),
                            'PostCode' : $('billing_postal_code').value,
                            'sessionid' : g_sessionID
                        },
                        onSuccess: function(transport){
                            g_bCreateWalletAndCheckFundsRunning = false;
                            if ( transport.responseText ){
                                try {
                                    var result = transport.responseText.evalJSON(true);
                                } catch ( e ) {
                                    // Failure
                                    OnCreateWalletAndCheckFundsFailure( 2 );
                                }
                                // Success...
                                if ( result.success == 1 ){
                                    OnCreateWalletAndCheckFundsSuccess( result );
                                    return;
                                }else{
                                    OnCreateWalletAndCheckFundsFailure( result.success );
                                    return;
                                }
                            }

                            OnCreateWalletAndCheckFundsFailure( 2  );
                        },
                        onFailure: function(){
                            g_bCreateWalletAndCheckFundsRunning = false;
                            OnCreateWalletAndCheckFundsFailure( 2  );
                        }
                    });
                }catch(e){
                    ReportRedeemJSError( 'Failed gathering form data and calling CreateWallet', e );
                }
            }

            function UpdateRedeemForm( result ){
                $('redeem_wallet_success_description').innerHTML = result.success_message;
                $('redeem_wallet_success_upsell_text').innerHTML = result.upsell_text;
                $('redeem_wallet_success_app_image_link').href = result.redirect_url;
                $('redeem_wallet_success_button').href = result.redirect_url;
                $('redeem_wallet_success_button_text').innerHTML = result.redirect_button_text;

                if ( result.bRedirectToApp ){
                    $('redeem_wallet_success_default_image').style.display = 'none';
                    $('redeem_wallet_success_image').src = result.redirect_image;
                    $('redeem_wallet_success_app_image').style.display = '';
                }else{
                    $('redeem_wallet_success_default_image').style.display = '';
                    $('redeem_wallet_success_app_image').style.display = 'none';
                }
            }

            function OnCreateWalletAndCheckFundsSuccess( result ){
                try{
                    $('error_display').innerHTML = '';
                    $('error_display').style.display = 'none';

                    g_sExchangedWalletCodeAmount = result.formattedcodeexchangeamount;
                    UpdateRedeemForm( result );

                    if ( result.currency != result.grant_currency ){
                        $('code_amount').innerHTML = g_sWalletCodeAmount;
                        $('code_exchange_amount').innerHTML = g_sExchangedWalletCodeAmount;

                        DisplayPage( 'redeem_amount' );
                    }else{
                        RedeemWalletCode();
                    }
                }catch( e ){
                    ReportRedeemJSError( 'Failed handling CreateWallet success', e );
                }
            }

            function OnCreateWalletAndCheckFundsFailure( detail ){
                try{
                    DisplayErrorMessage( '确认钱包时出现错误。您的钱包充值码尚未被兑换。<br>请联系 <a href="http://support.steampowered.com">Steam 客服</a>。' );
                    $('address_btn').style.display = '';
                    $('address_btn_in_progress').style.display = 'none';
                    $('validate_btn').style.display = '';
                    $('validate_btn_in_progress').style.display = 'none';
                }catch (e){
                    ReportRedeemJSError( 'Failed handling CreateWallet failure', e );
                }
            }


            var g_bRedeemWalletCodeRunning = false;
            function RedeemWalletCode(){
                if( g_bRedeemWalletCodeRunning )
                    return;

                try{
                    g_bRedeemWalletCodeRunning = true;

                    $('redeem_btn').style.display = 'none';
                    $('redeem_btn_in_progress').style.display = '';

                    new Ajax.Request('https://store.steampowered.com/account/confirmredeemwalletcode/',{
                        method:'post',
                        parameters: {
                            'wallet_code' : $jQuery('#inputKey').val().trim(),
                            'sessionid' : g_sessionID
                        },
                        onSuccess: function(transport){
                            g_bRedeemWalletCodeRunning = false;
                            if ( transport.responseText ){
                                try {
                                    var result = transport.responseText.evalJSON(true);
                                } catch ( e ) {
                                    // Failure
                                    OnRedeemWalletCodeFailure( 2 );
                                }
                                // Success...
                                if ( result.success == 1 ){
                                    OnRedeemWalletCodeSuccess( result );
                                    return;
                                }else{
                                    OnRedeemWalletCodeFailure( result.success, result.detail );
                                    return;
                                }
                            }

                            OnRedeemWalletCodeFailure( 2, 0  );
                        },
                        onFailure: function(){
                            g_bRedeemWalletCodeRunning = false;
                            OnRedeemWalletCodeFailure( 2, 0  );
                        }
                    });
                }catch(e){
                    ReportRedeemJSError( 'Failed gathering form data and calling RedeemWalletCode', e );
                }
            }


            function OnRedeemWalletCodeSuccess( result ){
                try{
                    $('wallet_current_balance').innerHTML = result.formattednewwalletbalance;
                    DisplayPage( 'code' );
                    showModal ( 'redirectStorePageModal', true );
                }catch( e ){
                    ReportRedeemJSError( 'Failed handling RedeemWalletCode success', e );
                }
            }

            function OnRedeemWalletCodeFailure( success, detail ){
                try{
                    var sErrorMessage = '发生了一个意外错误。您的 Steam 钱包充值码目前无法被兑换。请在 30 分钟后重新兑换该充值码。如果您仍然遇到问题,请联系 <a href="https://help.steampowered.com/wizard/HelpWithWalletCode">Steam 客服</a>寻求进一步的帮助。';

                    switch ( success ){
                        case 16:
                            sErrorMessage = '发生了一个意外错误。您的 Steam 钱包充值码目前无法被兑换。请在 30 分钟后重新兑换该充值码。如果您仍然遇到问题,请联系 <a href="https://help.steampowered.com/wizard/HelpWithWalletCode">Steam 客服</a>寻求进一步的帮助。';
                            break;

                        default:
                            switch ( detail ){
                                case 48:
                                    sErrorMessage = '您输入的 Steam 钱包充值码无效。重新输入时请仔细核对字符。';
                                    break;

                                case 14:
                                    sErrorMessage = '您输入的 Steam 钱包充值码无效。重新输入时请仔细核对字符。';
                                    break;

                                case 44:
                                    sErrorMessage = '您输入的 Steam 钱包充值码似乎有效;然而,您的 Steam 帐户目前在激活 Steam 钱包充值码时受到限制。请联系 <a href="https://support.steampowered.com/newticket.php?category=15">Steam 客服</a>寻求进一步的帮助。';
                                    break;

                                case 68:
                                    sErrorMessage = '您输入的 Steam 钱包充值码似乎有效,然而受制于美国政府法规,Steam 钱包一天内的流动金额为 2000 美元。请于 24 小时后重试。';
                                    break;

                                default:
                                    sErrorMessage = '发生了一个意外错误。您的 Steam 钱包充值码目前无法被兑换。请在 30 分钟后重新兑换该充值码。如果您仍然遇到问题,请联系 <a href="https://help.steampowered.com/wizard/HelpWithWalletCode">Steam 客服</a>寻求进一步的帮助。';
                                    break;
                            }
                            break;
                    }

                    DisplayErrorMessage( sErrorMessage );

                    $('redeem_btn').style.display = '';
                    $('redeem_btn_in_progress').style.display = 'none';
                    $('validate_btn').style.display = '';
                    $('validate_btn_in_progress').style.display = 'none';

                }catch (e){
                    ReportRedeemJSError( 'Failed handling RedeemWalletCode failure', e );
                }
            }

            function DisplayErrorMessage( strMessage ){
                $('error_display').innerHTML = strMessage;
                $('error_display').style.display = 'block';
                Effect.ScrollTo( 'error_display' );

                new Effect.Highlight( 'error_display', { endcolor : '#000000', startcolor : '#ff9900' } );
            }

            function ValidationMarkFieldBad( elem ){
                if ( $(elem) ){
                    if ( $(elem).hasClassName( 'highlight_on_error' ) )
                        new Effect.Morph( elem, {style: 'color: #FF9900', duration: 0.5 } );
                    else
                        new Effect.Morph( elem, {style: 'border-color: #FF9900', duration: 0.5 } )
                }
            }

            function ValidationMarkFieldOk( elem ){
                if ( $(elem) ){
                    if ( $(elem).hasClassName( 'highlight_on_error' ) )
                        $(elem).style.color='';
                    else
                        $(elem).style.borderColor = '';
                }
            }


            function redeemSubs(){
                redeemSub($jQuery('#inputKey').val().trim());
            }
            function redeemCode(){
                ValidateWalletCode();
            }

            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(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);
                            });
                        }
                    }
                }
            }
        }else{
            //激活页面内所有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.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=document.getElementsByTagName('body')[0].innerText;
                    allSteamKey=allSteamKey.match(/[\w\d]{5}(-[\w\d]{5}){2}/gim)||[];
                    allSteamKey=arr(allSteamKey)||[];
                    len=allSteamKey.length;
                    if(len>0){
                        hasKey.push(...allSteamKey);
                        hasKey=arr(hasKey);
                        keyList=hasKey.join(",");
                        $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(`
table.hclonely {
    font-family: verdana,arial,sans-serif;
    font-size: 11px;
    color: #333333;
    border-width: 1px;
    border-color: #999999;
    border-collapse: collapse;
}

table.hclonely th {
    background-color: #c3dde0;
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #a9c6c9;
}

table.hclonely tr {
    background-color: #d4e3e5;
}

table.hclonely td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #a9c6c9;
}

.swal-user {
    width: 80%;
}

table.hclonely a {
    color: #2196F3;
}

#unusedKeyArea code {
    padding: 2px 4px;
    font-size: 90%;
    color: #c7254e;
    background-color: #f9f2f4;
    border-radius: 3px;
}

.notice_box_content {
    border: 1px solid #a25024;
    border-radius: 3px;
    color: #acb2b8;
    font-size: 14px;
    font-family: "Motiva Sans", Sans-serif;
    font-weight: normal;
    padding: 15px 15px;
    margin-bottom: 15px;
}

.notice_box_content b {
    font-weight: normal;
    color: #f47b20;
    float: left;
}

#unusedKeys {
    margin:0 15px;
}

#copyUnuseKey span {
    font-size: 15px;
    line-height: 20px;
}

#unusedKeyArea li {
    white-space: nowrap;
    color: #007fff;
}

.currency_change_option_ctn {
	vertical-align: top;
	margin: 0 6%;
}
.currency_change_option_ctn:first-child {
	margin-bottom: 12px;
}
.currency_change_option_ctn > p {
	font-size: 12px;
	margin: 8px 8px 0 8px;
}
.currency_change_option_ctn {
	vertical-align: top;
	margin: 0 6%;
}
.currency_change_option_ctn:first-child {
	margin-bottom: 12px;
}

.currency_change_option {
			font-family: "Motiva Sans", Sans-serif;
		font-weight: 300; /* light */

			display: block;
}

.currency_change_option > span {
	display: block;
	padding: 9px 19px;
}

.currency_change_option .country {
	font-size: 20px;
}
.currency_change_option .notes {
	font-size: 13px;
	line-height: 18px;
}

.currency_change_option_ctn > p {
	font-size: 12px;
	margin: 8px 8px 0 8px;
}

.asf-class input[type="text"]{
    border: 1px solid #c2e9ee;
    width:180px;
}

.asf-output{
    width:90%;
    min-height:150px;
}

.switch-key {
    margin:0 15%;
    height:100px;
}
.switch-key-left {
    float:left;
}
.switch-key-right {
    float:right;
}

.switch-key div {
    width: 50%;
    position: relative;
    cursor:default;
}
.switch-key input {
    margin:10px 0;
}
.switch-key p {
    font-size:25px;
    height:25px;
    color:black;
    margin:0;
}
`);

        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){
        console.error("AuTo Redeemer Steamkey脚本执行出错: \n",e.stack);
    }

}());