Greasy Fork

来自缓存

Humble Choice Get Key

HB月包选择游戏(只选不刮),刮开游戏,刮开dlc,IG慈善包一键刮key

目前为 2020-06-16 提交的版本。查看 最新版本

   // ==UserScript==
    // @name         Humble Choice Get Key
    // @namespace    http://tampermonkey.net/
    // @version      0.13
    // @description  HB月包选择游戏(只选不刮),刮开游戏,刮开dlc,IG慈善包一键刮key
    // @author       ku mi
    // @include      /https:\/\/www\.humblebundle\.com\/subscription\/.*?/
    // @include      /https:\/\/www\.indiegala\.com\/(gift-bundle\/|gift\?gift_id=).*?/
    // @grant        GM_addStyle
    // @require      https://cdn.staticfile.org/html2canvas/0.5.0-beta4/html2canvas.min.js
    // ==/UserScript==
    //https:\/\/www\.(indiegala|humblebundle)\.com\/(subscription\/|gift-bundle\/|gift\?gift_id=).*?
     (function () {
       const init = {
         humblebundle,
         indiegala
       }
       init[window.location.hostname.split('.')[1]]()
        function indiegala() {
            const textarea = document.createElement('textarea')
            const li = document.createElement('li')
            const loading = document.createElement('i')
            loading.style.marginLeft = '10px'
            Object.assign(textarea.style,{ width: '500px', height: '150px', resize: 'none' })
            Object.assign(li.style, { marginLeft: '20px', width: '110px', height: '35px', color: '#fff', textAlign: 'center', lineHeight: '35px', cursor: 'pointer' })
            li.innerText = '刮开'
            li.className = 'active bg-gradient-blue'
            const div = document.querySelector('.profile-private-page-library-menu')
            li.appendChild(loading)
            div.appendChild(textarea)
            div.firstElementChild.appendChild(li)
            li.onclick = () => {
                const titles = [...document.querySelectorAll('.profile-private-page-library-key-cont [title]')].map(item => item.title)
                const gameIds = [...document.querySelectorAll('.profile-private-page-library-serial-dialog .right.profile-private-page-library-get-serial-btn.bg-gradient-blue')]
                const gameKeys = [...document.querySelectorAll('.profile-private-page-library-key-serial')]
                gameIds.length ? getKey() : showKey()
                function showKey(){
                  textarea.value = gameKeys.map((item, index) => titles[index] + '\t' + item.value).join('\n')
                }
                function getKey(){
                    loading.className = 'fa fa-spinner fa-spin'
                    gameKeys.forEach((item, index) => item.value.length && titles.splice(index, 1))
                    Promise.all(gameIds.map(item => {
                    const [, code, app_id] = item.getAttribute('onclick').match(/(?<=getSerialKey\(')(\w+)', '(\d+)',/)
                    return fetch('https://www.indiegala.com/library/get-serial-key', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json; charset=utf-8',
                            'x-requested-with': 'XMLHttpRequest'
                        },
                        body: JSON.stringify({
                            code,
                            app_id,
                            passcode: ''
                        })
                    })
                })).then(res => res.map(item => item.json())).then(res => Promise.all(res)).then(res => {
                        textarea.value = res.map((item, index) => titles[index] + '\t' + item.serial_key).join('\n')
                        loading.className = 'fa fa-check'
                        let time = setTimeout(() => {
                            loading.className = ''
                            clearTimeout(time)
                        }, 1000)
                    })
                }
            }
        }
        async function humblebundle() {
           const countryMap = {
               AD: '安道尔',
               AE: '阿拉伯联合酋长国',
               AF: '阿富汗',
               AG: '安提瓜和巴布达',
               AI: '安圭拉',
               AL: '阿尔巴尼亚',
               AM: '亚美尼亚',
               AO: '安哥拉',
               AQ: '南极洲',
               AR: '阿根廷',
               AS: '美属萨摩亚',
               AT: '奥地利',
               AU: '澳大利亚',
               AW: '阿鲁巴',
               AX: '奥兰群岛',
               AZ: '阿塞拜疆',
               BA: '波斯尼亚和黑塞哥维那',
               BB: '巴巴多斯',
               BD: '孟加拉',
               BE: '比利时',
               BF: '布基纳法索',
               BG: '保加利亚',
               BH: '巴林',
               BI: '布隆迪',
               BJ: '贝宁',
               BL: '圣巴托洛缪岛',
               BM: '百慕大',
               BN: '文莱',
               BO: '玻利维亚',
               BQ: '博奈尔',
               BR: '巴西',
               BS: '巴哈马',
               BT: '不丹',
               BU: '缅甸',
               BV: '布韦岛',
               BW: '博兹瓦纳',
               BY: '白俄罗斯',
               BZ: '伯利兹',
               CA: '加拿大',
               CC: '科科斯(基林)群岛',
               CD: '刚果(金)',
               CF: '中非共和国',
               CG: '刚果(布)',
               CH: '瑞士',
               CI: '科特迪瓦',
               CK: '库克群岛',
               CL: '智利',
               CM: '喀麦隆',
               CN: '中国',
               CO: '哥伦比亚',
               CR: '哥斯达黎加',
               CS: '塞尔维亚和黑山',
               CU: '古巴',
               CV: '佛得角',
               CW: '库拉索',
               CX: '圣诞岛',
               CY: '塞浦路斯',
               CZ: '捷克',
               DE: '德国',
               DJ: '吉布提',
               DK: '丹麦',
               DM: '多米尼克',
               DO: '多米尼加',
               DZ: '阿尔及利亚',
               EC: '厄瓜多尔',
               EE: '爱沙尼亚',
               EG: '埃及',
               EH: '西撒哈拉',
               ER: '厄立特里亚',
               ES: '西班牙',
               ET: '埃塞俄比亚',
               FI: '芬兰',
               FJ: '斐济',
               FK: '福克兰群岛',
               FM: '密克罗尼西亚',
               FO: '法罗群岛',
               FR: '法国',
               GA: '加蓬',
               GB: '英国',
               GD: '格林纳达',
               GE: '格鲁吉亚',
               GF: '法属圭亚那',
               GG: '根西',
               GH: '加纳',
               GI: '直布罗陀',
               GL: '格陵兰',
               GM: '冈比亚',
               GN: '几内亚',
               GP: '瓜德鲁普',
               GQ: '赤道几内亚',
               GR: '希腊',
               GS: '南乔治亚岛和南桑威奇群岛',
               GT: '危地马拉',
               GU: '关岛',
               GW: '几内亚比绍',
               GY: '圭亚那',
               HK: '香港',
               HM: '赫德岛和麦克唐纳群岛',
               HN: '洪都拉斯',
               HR: '克罗地亚',
               HT: '海地',
               HU: '匈牙利',
               ID: '印尼',
               IE: '爱尔兰',
               IL: '以色列',
               IM: '马恩岛',
               IN: '印度',
               IO: '英属印度洋领地',
               IQ: '伊拉克',
               IR: '伊朗',
               IS: '冰岛',
               IT: '意大利',
               JE: '泽西岛',
               JM: '牙买加',
               JO: '约旦',
               JP: '日本',
               KE: '肯尼亚',
               KG: '吉尔吉斯',
               KH: '柬埔寨',
               KI: '基里巴斯',
               KM: '科摩罗',
               KN: '圣基茨和尼维斯',
               KP: '朝鲜',
               KR: '韩国',
               KW: '科威特',
               KY: '开曼群岛',
               KZ: '哈萨克斯坦',
               LA: '老挝',
               LB: '黎巴嫩',
               LC: '圣卢西亚',
               LI: '列支敦士登',
               LK: '斯里兰卡',
               LR: '利比里亚',
               LS: '莱索托',
               LT: '立陶宛',
               LU: '卢森堡',
               LV: '拉脱维亚',
               LY: '利比亚',
               MA: '摩洛哥',
               MC: '摩纳哥',
               MD: '摩尔多瓦',
               ME: '黑山',
               MF: '法属圣马丁',
               MG: '马达加斯加',
               MH: '马绍尔群岛',
               MK: '马其顿',
               ML: '马里',
               MM: '缅甸',
               MN: '蒙古',
               MO: '澳门',
               MP: '北马里亚纳群岛',
               MQ: '马提尼克',
               MR: '毛里塔尼亚',
               MS: '蒙塞拉特',
               MT: '马耳他',
               MU: '毛里求斯',
               MV: '马尔代夫',
               MW: '马拉维',
               MX: '墨西哥',
               MY: '马来西亚',
               MZ: '莫桑比克',
               NA: '纳米比亚',
               NC: '新喀里多尼亚',
               NE: '尼日尔',
               NF: '诺福克岛',
               NG: '尼日利',
               NI: '尼加拉瓜',
               NL: '荷兰',
               NO: '挪威',
               NP: '尼泊尔',
               NR: '瑙鲁',
               NU: '纽埃',
               NZ: '新西兰',
               OM: '阿曼',
               PA: '巴拿马',
               PE: '秘鲁',
               PF: '法属波利尼西亚a',
               PG: '巴布亚新几内亚',
               PH: '菲律宾',
               PK: '巴基斯坦',
               PL: '波兰',
               PM: '圣皮埃尔和密克隆',
               PN: '皮特凯恩群岛',
               PR: '波多黎各',
               PS: '巴勒斯坦',
               PT: '葡萄牙',
               PW: '帕劳',
               PY: '巴拉圭',
               QA: '卡塔尔',
               RE: '留尼旺島',
               RO: '罗马尼亚',
               RS: '塞尔维亚',
               RU: '俄罗斯',
               RW: '卢旺达',
               SA: '沙特阿拉伯',
               SB: '所罗门群岛',
               SC: '塞舌尔',
               SD: '苏丹',
               SE: '瑞典',
               SG: '新加坡',
               SH: '圣赫勒拿、阿森松与特斯坦达库尼亚',
               SI: '斯洛文尼',
               SJ: '斯瓦尔巴群岛和扬马延岛',
               SK: '斯洛伐克',
               SL: '塞拉利昂',
               SM: '圣马力诺',
               SN: '塞内加尔',
               SO: '索马里',
               SR: '苏里南',
               SS: '南苏丹',
               ST: '圣多美和普林西比',
               SV: '萨尔瓦多',
               SX: '荷属圣马丁',
               SY: '叙利亚',
               SZ: '斯威士兰',
               TC: '特克斯和凯科斯群岛',
               TD: '乍得',
               TF: '法属南部领土',
               TG: '多哥',
               TH: '泰国',
               TJ: '塔吉克斯坦',
               TK: '托克劳',
               TL: '东帝汶',
               TM: '土库曼斯坦',
               TN: '突尼斯',
               TO: '汤加',
               TR: '土耳其',
               TT: '特立尼达和多巴哥',
               TV: '图瓦卢',
               TW: '台湾',
               TZ: '坦桑尼亚',
               UA: '乌克兰',
               UG: '乌干达',
               UM: '美国本土外小岛屿',
               US: '美国',
               UY: '乌拉圭',
               UZ: '乌兹别克斯坦',
               VA: '圣座',
               VC: '圣文森特和格林纳丁斯',
               VE: '委内瑞拉',
               VG: '英属维尔京群岛',
               VI: '美属维尔京群岛',
               VN: '越南',
               VU: '瓦努阿图',
               WF: '瓦利斯和富图纳群岛',
               WS: '萨摩亚',
               XK: '科索沃',
               YE: '也门',
               YT: '马约特',
               ZA: '南非',
               ZM: '赞比亚',
               ZW: '津巴布韦',
           }
           async function http(data, flag) {
               const res = await fetch(data.url, {
                   method: data.method || 'GET',
                   body: data.body || null,
                   headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
               })
               if(res.status !== 200) return {}
               return await flag ? res.text() : res.json()
           }
           const res = await http({url: location.href}, true)
           getInitData(new DOMParser().parseFromString(res, 'text/html'))
           function getInitData (el) {
               const script = el.getElementById('webpack-monthly-product-data') || el.getElementById('webpack-subscriber-hub-data')
               if(!script) return
               const {contentChoiceData, gamekey, contentChoicesMade, downloadPageUrl} = JSON.parse(script.innerText.trim()).contentChoiceOptions
               if(!gamekey) return
               const extrasUrl = {url: `https://www.humblebundle.com/api/v1/order/${gamekey}?wallet_data=true&all_tpkds=true`}
               const {content_choices, display_order, total_choices} = contentChoiceData.initial
               const selecedGame = contentChoicesMade ? contentChoicesMade.initial.choices_made : []
               const extras = contentChoiceData.extras.filter(item => item.types.includes('steam'))
               const allGame = display_order.map(item => {
                   let i = content_choices[item]
                   return {
                       machine_name: i.tpkds[0].machine_name,
                       title: i.tpkds[0].human_name,
                       exclusive: i.tpkds[0].exclusive_countries,
                       disallowed: i.tpkds[0].disallowed_countries,
                       appid: i.tpkds[0].steam_app_id || '',
                       name: item,
                       key: i.tpkds[0].redeemed_key_val || '',
                   }
               })
               const gameBox = document.createElement('div')
               const optionBox = document.createElement('div')
               gameBox.innerHTML = `<div class="_mask_"><div class="_alert_"></div></div><div class="_sh_box_"><button class="_sh_hd_ current">隐藏锁区信息</button><span style="margin-left: 20px; font-size: 20px; color: #c93756;">注: 锁区信息仅供参考,以激活后的SUB为准!</span><a class="_down_page_" target="_blank" href=${downloadPageUrl}>Download页面</a/></div><ul class="_self_view_"></ul>`
               optionBox.innerHTML = `<div class="_option_ul_"></div><div class="_select_ul_"></div><div style="display: flex;"><textarea class="_key_value_"></textarea><div><button class="_copy_">复制</button><button class="_clear_">清空</button></div></div>`
               const gamelist = gameBox.querySelector('._self_view_')
               const sButton = gameBox.querySelector('._sh_hd_')
               const sMask = gameBox.querySelector('._mask_')
               const sAlert = sMask.firstElementChild
               const textArr = ['选择游戏(只选不刮)','刮开/提取', '全选高亮', '取消高亮', '多选高亮截图']
               const classArr = ['._copy_','._clear_','._option_ul_','._select_ul_', '._key_value_']
               const [cButton, clearKey, optionUl, selectUl, keyValue] = classArr.map(item => optionBox.querySelector(item))
               const [selectKey, getKey, allLight, noLight, screenShot] = createButton()
               const liChild = createLiChild(allGame)
               setNum()
               eventInt()
               gameBox.insertBefore(optionBox, sMask)
               appendLi(allGame)
               const selectList = gamelist.querySelectorAll('li button:nth-child(2n+1)')
               const getList = gamelist.querySelectorAll('li button:nth-child(2n)')
               const view = document.querySelector('.content-choices-view')
               const list = document.querySelector(".content-choice-tiles.js-content-choice-tiles")
               view.insertBefore(gameBox, list)
               selectList.forEach(item => item.addEventListener('click', function(e){
                   if(this.classList.contains('current')) return
                   sendRquest(true, [this], e)
               }))
               getList.forEach(item => item.addEventListener('click', seake))
               checkHaveDlc(extras)
               async function seake (e) {
                   if(this.classList.contains('current')) return
                   if(this.dataset.name && !selecedGame.includes(this.dataset.name)){
                       const res = await sendRquest(false, [this], e)
                       if(!res) return alertFun(`刮开失败!๐·°(৹˃̵﹏˂̵৹)°·๐`)
                   }
                   sendKeyRquest([this], e)
               }
               function getZhName(arr) {
                   return arr.map(item => {
                       if (/\u53f0\u6e7e|\u4e2d\u56fd|\u9999\u6e2f|\u6fb3\u95e8/.test(countryMap[item])) return `<span style="color: #c93756; font-size: 20px;">${countryMap[item]}</span>`
                       return countryMap[item]
                   }).join('、')
               }
               function getLock(game) {
                   if (game.exclusive.length) return `<span style="color: #cc6699"><span style="color: #c93756; font-size: 20px;">只能在</span>以下激活:  ${getZhName(game.exclusive)}</span>`
                   if (game.disallowed.length) return `<span style="color: #B0E2FF"><span style="color: #c93756; font-size: 20px;">不能在</span>以下地区激活: ${getZhName(game.disallowed)}<span>`
                   return `<span style="color: #279b61">无限制激活</span>`
               }
               function alertFun(msg, flag) {
                   sAlert.innerHTML = msg
                   sMask.style.display = 'block'
                   sAlert.classList.add('_bunceIn_')
                   if(flag) return
                   let time = setTimeout(() => {
                       sMask.style.display = 'none'
                       sAlert.classList.remove('_bunceIn_')
                       clearTimeout(time)
                   }, 1200)
                   }
               async function selectGet(flag) {
                   if (flag && selecedGame.length >= total_choices) return alertFun(`已经没得选择了!(。•ˇ‸ˇ•。)`)
                   const newliChild = selectUl.querySelectorAll('button')
                   const noSelect = []
                   const noSelectLi = []
                   const selected = []
                   const no = flag ? selectList : getList
                   const arr = liChild.filter((li,index) => {
                       if(li.classList.contains('current') && (selected.length + noSelect.length < total_choices)) {
                           if(!flag && selecedGame.includes(li.dataset.name) && !li.dataset.key) selected.push(no[index])
                           else if(!selecedGame.includes(li.dataset.name) && (noSelect.length + selecedGame.length < total_choices)){
                               noSelect.push(no[index])
                               noSelectLi.push(li)
                           }
                       }
                       return li.classList.contains('current')
                   })
                   if(arr.length > total_choices) return alertFun(`最多选${total_choices}个!ヽ(#\`Д´)ノ`)
                   if(flag && !noSelect.length) return alertFun(`已经选过了!ヽ(#\`Д´)ノ`)
                   if(!flag && newliChild.length !== liChild.length) {
                       newliChild.forEach((li, index) => {
                           if(li.classList.contains('current') && !li.dataset.name){
                               arr.push(li)
                               if(!li.dataset.key)selected.push(no[index])
                           }
                       })
                   }
                   if(!arr.length) return
                   noLight.click()
                   if(noSelect.length){
                       const res = await sendRquest(flag, noSelect)
                       if(!res && !flag) return alertFun(`刮开失败!๐·°(৹˃̵﹏˂̵৹)°·๐`)
                       if(flag) return arr.forEach(item => selecedGame.includes(item.dataset.name) && (keyValue.value += `${item.dataset.title}: 选择成功\n`))
                   }
                   if(selected.length || noSelect.length) await sendKeyRquest(selected.concat(noSelect))
                   keyValue.value = ''
                   arr.forEach(item => item.dataset.key && (keyValue.value += `${item.dataset.title}\t${item.dataset.key}\n`))
               }
               async function sendKeyRquest (arr, e){
                   alertFun(`正在努力请求...!(,,•́ . •̀,,)`,true)
                   if(!e)keyValue.value = ''
                   const res = await Promise.all(arr.map(item => {
                       return http({
                           url: 'https://www.humblebundle.com/humbler/redeemkey',
                           body: `keytype=${item.dataset.machine_name}&key=${gamekey}&keyindex=0`,
                           method: 'POST'
                       })
                   }))
                   alertFun(`已经刮好了!(๑˃́ꇴ˂̀๑)`)
                   arr.forEach((item, index) => {
                       const newliChild = [...selectUl.querySelectorAll('button')]
                       newliChild.find(it => it.dataset.machine_name === item.dataset.machine_name).dataset.key = res[index].key || '刷新重试'
                       item.innerText = '已刮开'
                       item.className = 'current'
                       const input = item.nextElementSibling.nextElementSibling
                       input.style.display = 'block'
                       input.value = res[index].key || '刷新重试'
                       if(e) keyValue.value += `${item.dataset.title}\t${res[index].key}\n`
                   })
               }
               async function sendRquest(flag, arr, e) {
                   keyValue.value = ''
                   let url = `https://www.humblebundle.com/humbler/choosecontent?gamekey=${gamekey}&parent_identifier=initial`
                   arr.forEach(item => {
                       url += `&chosen_identifiers%5B%5D=${item.dataset.name}`
                   })
                   alertFun(`正在努力请求...!(,,•́ . •̀,,)`,true)
                   const res = await http({url})
                   if(flag) alertFun(res.force_refresh ? `已经选择好了!(๑˃́ꇴ˂̀๑)` : `选择失败!๐·°(৹˃̵﹏˂̵৹)°·๐`)
                   if(res.force_refresh) {
                       const titles = arr.map(item => {
                           const itemName = item.dataset.name
                           if(flag) {
                               item.innerText = '已选择'
                               item.className = 'current'
                           }else {
                               const next = item.nextElementSibling
                               next.innerText = '已选择'
                               next.className = 'current'
                           }
                           selecedGame.push(itemName)
                           if(e && flag) keyValue.value += `${item.dataset.title}: 选择成功\n`
                           return item.dataset.title.toLocaleLowerCase()

                       })
                       checkHaveDlc(titles, true)
                   }else {
                       arr.forEach(item => {
                           if(e && flag) keyValue.value += `${item.dataset.title}: 选择失败\n`
                       })
                   }
                   return res.force_refresh
               }
               async function checkHaveDlc(arr, flag) {
                   if(!arr.length) return
                   const extrasRes = await http(extrasUrl)
                   let dlc = flag ? extrasRes.tpkd_dict.all_tpks.filter(item => arr.some(it => it !== item.human_name.toLocaleLowerCase() && item.human_name.toLocaleLowerCase().indexOf(it) === 0)) : extrasRes.tpkd_dict.all_tpks.filter(item => arr.some(it => it.machine_name === item.machine_name))
                   dlc = dlc.map(item => ({
                       machine_name: item.machine_name,
                       title: item.human_name,
                       exclusive: item.exclusive_countries,
                       disallowed: item.disallowed_countries,
                       appid: item.steam_app_id || '',
                       name: '',
                       key: item.redeemed_key_val || ''
                   }))
                   if(!dlc.length) return
                   createLiChild(dlc, true)
                   appendLi(dlc)
               }
               function appendLi(data){
                   const fragment = document.createDocumentFragment()
                   data.forEach(item => {
                       const li = document.createElement('li')
                       li.innerHTML = `<div style="width: 100%;"><a style="text-decoration: none; color: #169fe3" ${item.appid && `href="https://store.steampowered.com/app/${item.appid}"`} target="_blank">${item.title}</a><button class="${item.key ? 'current' : ''}" data-name="${item.name}" data-machine_name="${item.machine_name}"  data-title="${item.title}">${item.key ? '已刮开' : '未刮开'}</button><button ${item.name ? '' : `style="visibility: hidden"` } class="${selecedGame.includes(item.name) ? 'current' : ''}" data-name="${item.name}" data-machine_name="${item.machine_name}" data-title="${item.title}">${selecedGame.includes(item.name) ? '已选择' : '未选择'}</button><input type="text" class="_click_key_" ${item.key ? '' : `style="display: none"`} value=${item.key}><p style="margin: 15px 15px 15px 0; ">${getLock(item)}</p></div>`
                       fragment.appendChild(li)
                       li.querySelector('button').addEventListener('click', seake)
                   })
                   gamelist.appendChild(fragment)
               }
               function createButton(){
                   const fragment = document.createDocumentFragment()
                   const buttonList = textArr.map((item, index) => {
                       const button = document.createElement('button')
                       button.innerText = item
                       fragment.appendChild(button)
                       return button
                   })
                   optionUl.appendChild(fragment)
                   return buttonList
               }
               function createLiChild (arr, flag) {
                   const fragment = document.createDocumentFragment()
                   const liChild = arr.map((item, index) => {
                       const button = document.createElement('button')
                       button.innerText = flag ? 'DLC' : index + 1
                       Object.assign(button.dataset, {
                           name: item.name,
                           title: item.title,
                           key: item.key,
                           machine_name: item.machine_name
                       })
                       fragment.appendChild(button)
                       return button
                   })
                   selectUl.appendChild(fragment)
                   return liChild
               }
               function setNum() {
                   const els = document.querySelectorAll('.js-content-choices .choice-image-container')
                   els.forEach((item, index) => {
                       let div = document.createElement('div')
                       div.setAttribute('class','_game_num_')
                       div.innerText = index + 1
                       item.appendChild(div)
                   })
               }
               function eventInt(){
                   optionUl.onselectstart = () => false
                   selectUl.onselectstart = () => false
                   selectUl.addEventListener('click',(e) => {if (e.target.nodeName === 'BUTTON') e.target.classList.toggle('current')})
                   allLight.addEventListener('click', () => selectUl.querySelectorAll('button').forEach(item => item.classList.add('current')))
                   noLight.addEventListener('click', () => selectUl.querySelectorAll('button').forEach(item => item.classList.remove('current')))
                   clearKey.addEventListener('click',() => (keyValue.value = ''))
                   cButton.addEventListener('click', () => {
                       if(!keyValue.value.length) return
                       keyValue.select()
                       document.execCommand('copy')
                   })
                   clearKey.addEventListener('click', () => (keyValue.value = ''))
                   sButton.addEventListener('click', function () {
                       const flag = this.classList.contains('current')
                       gamelist.classList.remove(flag ? '_slide_down_' : '_slide_up_')
                       gamelist.classList.add(flag ? '_slide_up_': '_slide_down_')
                       this.innerText = flag ? '显示锁区信息' : '隐藏锁区信息'
                       this.classList.toggle('current')
                   })
                   getKey.addEventListener('click', () => selectGet())
                   selectKey.addEventListener('click', () => selectGet(true))
                   screenShot.addEventListener('click', () => {
                       let flag
                       const newButton = selectUl.querySelectorAll('button')
                       if(!sButton.classList.contains('current')) sButton.click()
                       const arr = [...gamelist.children].filter((item, index) => !newButton[index].classList.contains('current'))
                       if(arr.length !== newButton.length) arr.forEach(item => (item.style.display = 'none'))
                       alertFun(`正在截图...(,,•́ . •̀,,)`, true)
                       sMask.onclick = () => {
                           arr.forEach(item => (item.style.display = 'block'))
                           sMask.style.display = 'none'
                           flag = true
                           sMask.onclick = null
                       }
                       html2canvas(gamelist).then(canvas => {
                           if(flag) return
                           sAlert.style.backgroundColor = '#494f5c'
                           alertFun(`<img src=${canvas.toDataURL()}>`,true)
                           sMask.onclick = () => {
                               arr.forEach(item => (item.style.display = 'block'))
                               sMask.style.display = 'none'
                               sAlert.style.backgroundColor = '#c93756'
                               sMask.onclick = null
                               noLight.click()
                           }
                       })
                   })
               }
            GM_addStyle(`._click_key_{border-radius:4px;outline:none;border:none;background-color:#454c5e;width:250px;padding:5px 0;text-align:center;float:right;}._mask_{position:fixed;left:0;top:0;bottom:0;right:0;display:none;background-color:rgba(0,0,0,.3);z-index:999;}._alert_{background-color:#c93756;border-radius:8px;box-shadow:0 0 15px #c93756;font-size:1.5em;position:absolute;text-align:center;left:50%;top:50%;padding:0 30px;line-height:3em;translate(-50%,-50%)}._alert_ img{display:block;}._bunceIn_{animation:bunceIn .3s forwards;}._sh_hd_{border:none;outline:none;color:#A4D7F5;background-image:linear-gradient( to bottom,rgba(47,137,188,1) 5%,rgba(23,67,92,1) 95%);margin:20px 0 0 20px;border-radius:5px;line-height:50px;padding:0 20px;}._slide_down_{animation:slideDown .3s forwards;}._slide_up_{animation:slideUp .3s forwards;}@keyframes bunceIn{0%{transform:translate(-50%,-50%)  scale(.8);}50%{transform:translate(-50%,-50%) scale(1.2);}100%{transform:translate(-50%,-50%) scale(1);}}@keyframes slideUp{0%{max-height:2000px;}100%{max-height:0;}}@keyframes slideDown{0%{max-height:0;}100%{max-height:2000px;}}._down_page_{float:right;padding:0 20px;border-radius:5px;height:50px;margin:20px 20px 0 0;line-height:50px;background:linear-gradient( to bottom,rgba(47,137,188,1) 5%,rgba(23,67,92,1) 95%);color:#A4D7F5;text-decoration:none;}._key_value_{margin:20px 0 0 20px;width:650px;height:200px;resize:none;font-size:18px;color:#fff;outline:none;background-color:#454c5e;border:none;}._option_ul_,._select_ul_{margin:0 0 0 20px;line-height:50px;}._option_ul_>button,._select_ul_>button{border:none;outline:none;padding:0 20px;margin:20px 20px 0 0;border-radius:5px;font-size:16px;background-image:linear-gradient( to bottom,rgba(47,137,188,1) 5%,rgba(23,67,92,1) 95%);}._select_ul_>button{background:#454c5e;}._select_ul_> button.current{background-image:linear-gradient(to top,#0c3483 0%,#a2b6df 100%,#6b8cce 100%,#a2b6df 100%);}._game_num_{width:100%;height:100%;position:absolute;left:0;top:0;z-index:1;background-color:rgba(0,0,0,.3);text-align:center;font-size:100px;}._sh_hd_.current{background-image:linear-gradient(to top,#c71d6f 0%,#d09693 100%);color:#fff;}._self_view_{max-height:2000px;list-style:none;margin:20px 0 0 0;padding:0;overflow:hidden;background-color:#363c49;}._self_view_>li{font-size:16px;padding:20px 0 0px 20px;border-bottom:10px solid #454c5e;display:flex;justify-content:space-between;}._self_view_>li button{border:none;outline:none;background-image:linear-gradient( to bottom,rgba(47,137,188,1) 5%,rgba(23,67,92,1) 95%);color:#A4D7F5;margin:0 10px;font-size:16px;border-radius:0.8em;padding:5px 15px;width:100px;float:right;}._copy_,._clear_{background:linear-gradient( to bottom,rgba(47,137,188,1) 5%,rgba(23,67,92,1) 95%);color:#A4D7F5;border-radius:5px;border:none;outline:none;font-size:16px;line-height:50px;text-align:center;margin:170px 0 0 20px;width:70px;}._self_view_>li .current{opacity:0.45;}._self_view_>li:last-child{border:none;}`)
           }
        }
    })();