// ==UserScript== // @name AuTo Redeem Steamkey // @namespace HCLonely // @author HCLonely // @description 复制网页中的Steamkey后自动激活,3.0+版本为Beta版 // @version 3.4.0 // @supportURL https://keylol.com/t344489-1-1 // @homepage https://blog.hclonely.com/posts/71381355/ // @iconURL https://blog.hclonely.com/img/avatar.jpg // @include *://*/* // @exclude *store.steampowered.com/widget/* // @exclude *googleads* // @grant GM_setClipboard // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @run-at document-idle // @require https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js // @require https://cdn.jsdelivr.net/npm/sweetalert@2.1.2/dist/sweetalert.min.js // @connect * // @compatible chrome 没有测试其他浏览器的兼容性 // @downloadURL none // ==/UserScript== "use strict"; // asfCmd.ts var asfCommands = `
命令 权限 描述
2fa [Bots] Master 为指定机器人生成临时的​两步验证​令牌。
2fafinalize [Bots] <ActivationCode> Master 使用短信或邮件验证码,完成为指定机器人绑定新两步验证凭据的流程。
2fafinalized [Bots] <ActivationCode> Master 为指定机器人导入已创建完成的两步验证凭据,并用两步验证令牌代码验证。
2fafinalizedforce [Bots] Master 为指定机器人导入已创建完成的两步验证凭据,并跳过两步验证令牌代码验证。
2fainit [Bots] Master 开始为指定机器人绑定新两步验证凭据的流程。
2fano [Bots] Master 为指定机器人拒绝所有等待操作的两步验证交易确认。
2faok [Bots] Master 为指定机器人接受所有等待操作的两步验证交易确认。
addlicense [Bots] <Licenses> Operator 为指定机器人激活给定的 Licenses (许可),该参数解释详见下文
balance [Bots] Master 显示指定机器人的 Steam 钱包余额。
bgr [Bots] Master 显示指定机器人的 BGR(后台游戏激活器)队列信息。
bgrclear [Bots] Master 清除指定机器人的后台游戏激活器队列。
encrypt <encryptionMethod> <stringToEncrypt> Owner 以给定的加密方式加密字符串——详见下文的解释
exit Owner 完全停止 ASF 进程。
farm [Bots] Master 重新启动指定机器人的挂卡模块。
fb [Bots] Master 列出指定机器人的自动挂卡黑名单。
fbadd [Bots] <AppIDs> Master 将给定的 AppIDs 加入指定机器人的自动挂卡黑名单。
fbrm [Bots] <AppIDs> Master 将给定的 AppIDs 从指定机器人的自动挂卡黑名单中移除。
fq [Bots] Master 列出指定机器人的优先挂卡队列。
fqadd [Bots] <AppIDs> Master 将给定的 AppIDs 加入指定机器人的优先挂卡队列。
fqrm [Bots] <AppIDs> Master 将给定的 AppIDs 从指定机器人的优先挂卡队列中移除。
hash <hashingMethod> <stringToHash> Owner 以指定的加密方式生成给定字符串的哈希值——详见下文的解释
help FamilySharing 显示帮助(指向此页面的链接)。
input [Bots] <Type> <Value> Master 为指定机器人填写给定的输入值,仅在 Headless 模式中可用——详见下文的解释
inventory [Bots] Operator 显示指定机器人的库存摘要。
level [Bots] Master 显示指定机器人的 Steam 帐户等级。
loot [Bots] Master 将指定机器人的所有 LootableTypes 社区物品拾取到其 SteamUserPermissions 属性中设置的 Master 用户(如果有多个则取 steamID 最小的)。
loot@ [Bots] <AppIDs> Master 将指定机器人的所有符合给定 AppIDsLootableTypes 社区物品拾取到其 SteamUserPermissions 属性中设置的 Master 用户(如果有多个则取 steamID 最小的)。 此命令与 loot% 相反。
loot% [Bots] <AppIDs> Master 将指定机器人的所有不符合给定 AppIDsLootableTypes 社区物品拾取到其 SteamUserPermissions 属性中设置的 Master 用户(如果有多个则取 steamID 最小的)。 此命令与 loot@ 相反。
loot^ [Bots] <AppID> <ContextID> Master 将指定机器人的 ContextID 库存分类中符合给定 AppID 的物品拾取到其 SteamUserPermissions 属性中设置的 Master 用户(如果有多个则取 steamID 最小的)。
loot& [Bots] <AppID> <ContextID> <Rarities> Master 将指定机器人的 ContextID 库存分类中符合给定 AppID 并且符合给定 Rarities 的物品拾取到其 SteamUserPermissions 属性中设置的 Master 用户(如果有多个则取 steamID 最小的)。
mab [Bots] Master 列出 MatchActively 自动交易的 App 黑名单。
mabadd [Bots] <AppIDs> Master 将给定的 AppIDs 加入到 MatchActively 自动交易的 App 黑名单。
mabrm [Bots] <AppIDs> Master 将给定的 AppIDsMatchActively 自动交易的 App 黑名单中移除。
match [Bots] Master 控制 ItemsMatcherPlugin 的特殊命令,用于立即触发 MatchActively 流程。
nickname [Bots] <Nickname> Master 将指定机器人的昵称更改为 Nickname
owns [Bots] <Games> Operator 检查指定机器人是否已拥有 Games,该参数解释详见下文
pause [Bots] Operator 永久暂停指定机器人的自动挂卡模块。 ASF 在本次会话中将不会再尝试对此帐户进行挂卡,除非您手动 resume 或者重启 ASF。
pause~ [Bots] FamilySharing 临时暂停指定机器人的自动挂卡模块。 挂卡进程将会在下次游戏事件或者机器人断开连接时自动恢复。 您可以 resume 以恢复挂卡。
pause& [Bots] <Seconds> Operator 临时暂停指定机器人的自动挂卡模块 Seconds 秒。 之后,挂卡模块会自动恢复。
play [Bots] <AppIDs,GameName> Master 切换到手动挂卡——使指定机器人运行给定的 AppIDs,并且可选自定义 GameName 为游戏名称。 若要此功能正常工作,您的 Steam 帐户必须拥有所有您指定的 AppIDs 的有效许可,包括免费游戏。 使用 resetresume 命令恢复。
points [Bots] Master 显示指定机器人的 Steam 点数商店点数余额。
privacy [Bots] <Settings> Master 更改指定机器人的 Steam 隐私设置,可用选项见下文
redeem [Bots] <Keys> Operator 为指定机器人激活给定的游戏序列号或钱包充值码。
redeem^ [Bots] <Modes> <Keys> Operator Modes 模式为指定机器人激活给定的游戏序列号或钱包充值码,模式详见下文的解释
redeempoints [Bots] <DefinitionIDs> Operator 为指定机器人以 Steam 点数兑换给定物品。 默认只允许免费物品,如果要无条件兑换物品,包括付费物品,则需要在每个符合条件的物品 DefinitionID 结尾添加 ! 符号。
reset [Bots] Master 重置为原始(之前的)游玩状态,用来配合 play 命令的手动挂卡模式使用。
restart Owner 重新启动 ASF 进程。
resume [Bots] FamilySharing 恢复指定机器人的自动挂卡进程。
start [Bots] Master 启动指定机器人。
stats Owner 显示进程统计信息,例如托管内存用量。
status [Bots] FamilySharing 显示指定机器人的状态。
std [Bots] Master 控制 SteamTokenDumperPlugin 的特殊命令,用于触发刷新指定的机器人并立即提交数据。
stop [Bots] Master 停止指定机器人。
tb [Bots] Master 列出指定机器人的交易黑名单用户。
tbadd [Bots] <SteamIDs64> Master 将给定的 SteamIDs 加入指定机器人的交易黑名单。
tbrm [Bots] <SteamIDs64> Master 将给定的 SteamIDs 从指定机器人的交易黑名单中移除。
transfer [Bots] <TargetBot> Master 将指定机器人的所有 TransferableTypes 社区物品转移到一个目标机器人。
transfer@ [Bots] <AppIDs> <TargetBot> Master 将指定机器人的所有符合给定 AppIDsTransferableTypes 社区物品转移到一个目标机器人。 此命令与 transfer% 相反。
transfer% [Bots] <AppIDs> <TargetBot> Master 将指定机器人的所有不符合给定 AppIDsTransferableTypes 社区物品转移到一个目标机器人。 此命令与 transfer@ 相反。
transfer^ [Bots] <AppID> <ContextID> <TargetBot> Master 将指定机器人的 ContextID 库存分类中符合给定 AppID 的物品转移到一个目标机器人。
transfer& [Bots] <AppID> <ContextID> <TargetBot> <Rarities> Master 将指定机器人的 ContextID 库存分类中符合给定 AppID 并且符合给定 Rarities 的物品转移到一个目标机器人。
unpack [Bots] Master 拆开指定机器人库存中的所有补充包。
update [Channel] Owner 在 GitHub 上检查 ASF 新版本,如果可用则更新。 通常这会每隔 UpdatePeriod 自动执行一次。 可选的 Channel 参数指定 UpdateChannel,如果未提供,则默认使用全局设置中的值。 Channel 可以用 ! 字符结尾,这会强制在指定频道上更新——包括降级等操作。
updateplugins [Channel] [Plugins] Owner 更新指定的插件。 如果插件支持多个更新频道,可选的 Channel 参数允许您选择不同的 UpdateChannel 进行更新。 Channel 可以用 ! 字符结尾,这会强制在指定频道上更新——包括降级等操作,但具体的功能取决于插件自身。 如果不指定 Plugins,则所有由 PluginsUpdateListPluginsUpdateMode 配置判断为允许自动更新的插件都会被更新。 如果您要更新指定插件,特别是已经默认禁用自动更新的,则需要同时提供 ChannelPlugins 参数,这样 ASF 就会忽略其自动更新设置,强行更新它们。
version FamilySharing 显示 ASF 的版本号。
`; // asf.ts var getASFConfig = (setting) => ({ protocol: setting.asfProtocol, host: setting.asfHost, port: setting.asfPort, password: setting.asfPassword }); var getASFHeaders = (setting) => { const { protocol, host, port } = getASFConfig(setting); return { accept: "application/json", "Content-Type": "application/json", Authentication: setting.asfPassword, Host: `${host}:${port}`, Origin: `${protocol}://${host}:${port}`, Referer: `${protocol}://${host}:${port}/page/commands` }; }; var getASFUrl = (setting) => { const { protocol, host, port } = getASFConfig(setting); return `${protocol}://${host}:${port}/Api/Command`; }; function asfSend(command = "") { const setting = GM_getValue("setting") || globalThis.defaultSetting; if (!setting?.asf) { swal({ closeOnClickOutside: false, className: "swal-user", icon: "warning", title: "此功能需要在设置中配置ASF IPC并开启ASF功能!", //@ts-ignore buttons: { confirm: "确定" } }); return; } swal({ closeOnClickOutside: false, className: "swal-user", text: "请在下方输入要执行的ASF指令:", content: { element: "input", attributes: { placeholder: "输入ASF指令" } }, //@ts-ignore buttons: { test: "连接测试", redeem: "激活key", pause: "暂停挂卡", resume: "恢复挂卡", "2fa": "获取令牌", "2faok": "2faok", more: "更多ASF指令", confirm: "确定", cancel: "取消" } }).then((value) => { switch (value) { case "redeem": swalRedeem(); break; case "pause": case "resume": case "2fa": case "2faok": asfRedeem(`!${value}`); break; case "test": asfTest(); break; case "more": swal({ closeOnClickOutside: false, className: "swal-user", text: "ASF指令", //@ts-ignore content: $(asfCommands)[0], //@ts-ignore buttons: { confirm: "返回", cancel: "关闭" } }).then((value2) => { if (value2) asfSend(); }); $("table.hclonely button.swal-button").on("click", function() { const command2 = setting.asfBot ? $(this).parent().next().text().trim().replace(//gim, setting.asfBot) : $(this).parent().next().text().trim(); asfSend(command2); }); break; case null: break; default: const inputValue = $(".swal-content__input").val()?.toString()?.trim(); if (!inputValue) { swal({ closeOnClickOutside: false, title: "ASF指令不能为空!", icon: "warning", //@ts-ignore buttons: { confirm: "确定" } }).then(() => { asfSend(command); }); } else { const finalCommand = value || inputValue; if (finalCommand) asfRedeem(finalCommand); } break; } }); if (command) { $(".swal-content__input").val(`!${command}`); } } function swalRedeem() { swal({ closeOnClickOutside: false, className: "swal-user", title: "请输入要激活的key:", //@ts-ignore content: $('')[0], //@ts-ignore buttons: { confirm: "激活", cancel: "返回" } }).then((value) => { if (value) { const key = getKeysByRE($("#keyText").val()?.toString()?.trim() || ""); if (key.length > 0) { const setting = GM_getValue("setting") || globalThis.defaultSetting; const asfBot = setting.asfBot ? `${setting.asfBot} ` : ""; asfRedeem(`!redeem ${asfBot}${key.join(",")}`); } else { swal({ closeOnClickOutside: false, title: "steam key不能为空!", icon: "error", //@ts-ignore buttons: { confirm: "返回", cancel: "关闭" } }).then((value2) => { if (value2) { swalRedeem(); } }); } } else { asfSend(); } }); } function asfTest() { const setting = GM_getValue("setting") || globalThis.defaultSetting; if (!setting.asf) { swal({ closeOnClickOutside: false, title: "请先在设置中开启ASF功能", icon: "warning", //@ts-ignore buttons: { confirm: "确定" } }); return; } const apiUrl = getASFUrl(setting); swal({ closeOnClickOutside: false, title: "ASF连接测试", text: `正在尝试连接 "${apiUrl}"`, //@ts-ignore buttons: { confirm: "确定" } }); GM_xmlhttpRequest({ method: "POST", url: apiUrl, data: '{"Command":"!stats"}', responseType: "json", headers: getASFHeaders(setting), onload(data) { const response = data.response; if (data.status === 200) { if (response?.Success === true && response.Message === "OK" && response.Result) { swal({ closeOnClickOutside: false, title: "ASF连接成功!", icon: "success", text: `连接地址 "${apiUrl}" 返回内容 "${response.Result.trim()}"`, //@ts-ignore buttons: { confirm: "确定" } }); } else if (response?.Message) { swal({ closeOnClickOutside: false, title: "ASF连接成功?", icon: "info", text: `连接地址 "${apiUrl}" 返回内容 "${response.Message.trim()}"`, //@ts-ignore buttons: { confirm: "确定" } }); } else { swal({ closeOnClickOutside: false, title: "ASF连接失败!", icon: "error", text: `连接地址 "${apiUrl}" 返回内容 "${data.responseText}"`, //@ts-ignore buttons: { confirm: "确定" } }); } } else { swal({ closeOnClickOutside: false, title: `ASF连接失败:${data.status}`, icon: "error", text: `连接地址 "${apiUrl}"`, //@ts-ignore buttons: { confirm: "确定" } }); } }, onabort() { showErrorDialog("ASF连接失败:aborted", apiUrl); }, onerror() { showErrorDialog("ASF连接失败:error", apiUrl); }, ontimeout() { showErrorDialog("ASF连接失败:timeout", apiUrl); } }); } function showErrorDialog(title, apiUrl) { swal({ closeOnClickOutside: false, title, icon: "error", text: `连接地址 "${apiUrl}"`, //@ts-ignore buttons: { confirm: "确定" } }); } function asfRedeem(command) { const setting = GM_getValue("setting") || globalThis.defaultSetting; const apiUrl = getASFUrl(setting); const textarea = document.createElement("textarea"); textarea.setAttribute("class", "asf-output"); textarea.setAttribute("readonly", "readonly"); const btn = /!redeem/gim.test(command) ? { confirm: "提取未使用key", cancel: "关闭" } : { confirm: "确定" }; swal({ closeOnClickOutside: false, className: "swal-user", text: `正在执行ASF指令:${command}`, //@ts-ignore content: textarea, //@ts-ignore buttons: btn }).then((v) => { if (/!redeem/gim.test(command)) { let value = ""; const textareaElement = $(".swal-content textarea"); if (textareaElement.length > 0) { value = textareaElement.val()?.toString() || ""; } GM_setValue("history", [$(".swal-content").html() || "", value]); if (v) { const unUseKey = textareaElement.val()?.toString()?.split(/[(\r\n)\r\n]+/).filter((e) => /未使用/gim.test(e || "")).join(","); if (unUseKey) { GM_setClipboard(arr(getKeysByRE(unUseKey)).join(",")); swal({ title: "复制成功!", icon: "success" }); } } } }); GM_xmlhttpRequest({ method: "POST", url: apiUrl, data: JSON.stringify({ Command: command }), responseType: "json", headers: getASFHeaders(setting), onload(data) { console.log(data); console.log(command); if (data.status === 200) { if (data.response?.Success && data.response.Message === "OK" && data.response.Result) { textarea.value += `${data.response.Result.trim()} `; } else if (data.response?.Message) { textarea.value += `${data.response.Message.trim()} `; } else { textarea.value += data.responseText || ""; } } else { swal({ closeOnClickOutside: false, className: "swal-user", title: `执行ASF指令(${command})失败!请检查ASF配置是否正确!`, text: data.responseText || data.status.toString(), icon: "error", //@ts-ignore buttons: { confirm: "关闭" } }); } }, onabort() { swal({ closeOnClickOutside: false, className: "swal-user", title: `执行ASF指令(${command})失败!请检查网络!`, text: "aborted", icon: "error", //@ts-ignore buttons: { confirm: "关闭" } }); }, onerror(error) { console.error(error); swal({ closeOnClickOutside: false, className: "swal-user", title: `执行ASF指令(${command})失败!请检查控制台日志!`, text: "error", icon: "error", //@ts-ignore buttons: { confirm: "关闭" } }); }, ontimeout() { swal({ closeOnClickOutside: false, className: "swal-user", title: `执行ASF指令(${command})失败!请检查网络!`, text: "连接超时", icon: "error", //@ts-ignore buttons: { confirm: "关闭" } }); } }); } // utils.ts function mouseClick($2, e) { const $i = $2("").text("Steam Key"); const x = e.pageX; const y = e.pageY; $i.css({ "z-index": 999999999999999, top: y - 20, left: x, position: "absolute", "font-weight": "bold", color: "#ff6651" }); $2("body").append($i); $i.animate({ top: y - 180, opacity: 0 }, 1500, () => { $i.remove(); }); } function addBtn() { const div = $('
'); const btn = $('')[0]; btn.onclick = function() { const setting = GM_getValue("setting") || {}; const keys = getKeysByRE($(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.join(",")); } }; div.append(btn); $("body").append(div); return btn; } function redeemAllKey() { let len = 0; let keyList = ""; let hasKey = []; const btn = addBtn(); setInterval(() => { const allSteamKey = arr(getKeysByRE($("body").text() || "")) || []; len = allSteamKey.length; if (len > 0) { hasKey.push(...allSteamKey); hasKey = arr(hasKey); keyList = hasKey.join(","); if ($(btn).attr("key") !== keyList) { $(btn).attr("key", keyList).text(`激活本页面所有key(共${hasKey.length}个)`).show(); } } else if (document.getElementById("allKey")?.style?.display === "block") { $(btn).hide().text("激活本页面所有key(共0个)"); } }, 1e3); } function arr(arr2) { return [...new Set(arr2)]; } async function httpRequest(options, times = 0) { if (window.TRACE) { console.trace("%cAuto-Task[Debug]:", "color:blue"); } try { const result = await new Promise((resolve) => { if (options.dataType) { options.responseType = options.dataType; } const requestObj = { timeout: 3e4, ontimeout(data) { resolve({ result: "Error", statusText: "Timeout", status: 601, data, options }); }, onabort(data) { resolve({ result: "Error", statusText: "Aborted", status: 602, data, options }); }, onerror(data) { resolve({ result: "Error", statusText: "Error", status: 603, data, options }); }, onload(data) { if (options.responseType === "json" && data?.responseText && typeof data.response !== "object") { try { data.response = JSON.parse(data.responseText); } catch (error) { } } resolve({ result: "Success", statusText: "Load", status: 600, data, options }); }, ...options }; GM_xmlhttpRequest(requestObj); }); if (window.DEBUG) { console.log("%cAuto-Task[httpRequest]:", "color:blue", JSON.stringify(result)); } if (result.status !== 600 && times < 2) { return await httpRequest(options, times + 1); } return result; } catch (error) { console.log("%cAuto-Task[httpRequest]:", "color:red", JSON.stringify({ errorMsg: error, options })); return { result: "JsError", statusText: "Error", status: 604, error, options }; } } function settingChange() { const setting = GM_getValue("setting") || globalThis.defaultSetting; const div = $(`
新标签页激活
开启复制捕捉 开启选中捕捉 开启点击捕捉
捕捉页面内所有key
ASF IPC设置
ASF IPC协议
ASF IPC地址
ASF IPC端口
ASF IPC密码
ASF Bot名字
开启ASF激活
`)[0]; swal({ closeOnClickOutside: false, className: "asf-class", title: "全局设置", content: div, buttons: { save: "保存", showHistory: "上次激活记录", showSwitchKey: "Key格式转换", cancel: "取消" } }).then((value) => { if (value === "save") { const newSetting = {}; $("#hclonely-asf input").each(function(index, element) { const name = $(element).attr("name"); if (name) { newSetting[name] = element.type === "checkbox" ? element.checked : element.value; } }); GM_setValue("setting", newSetting); swal({ closeOnClickOutside: false, icon: "success", title: "保存成功!", text: "刷新页面后生效!", buttons: { confirm: "确定" } }); } else if (value === "showHistory") { showHistory(); } else if (value === "showSwitchKey") { showSwitchKey(); } }); } function showHistory() { const history = GM_getValue("history"); if (Array.isArray(history)) { swal({ closeOnClickOutside: false, className: "swal-user", title: "上次激活记录:", content: $(history[0])[0], buttons: { confirm: "确定" } }); if (history[1]) { $(".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: $('

key

key

key

 

key,key,key

 

')[0] }).then((value) => { if (value) { const selectedValue = $("input:radio:checked").val(); if (selectedValue) { showSwitchArea(selectedValue); } else { swal({ closeOnClickOutside: false, title: "请选择要将key转换成什么格式!", icon: "warning" }).then(() => showSwitchKey()); } } }); $(".switch-key div").each(function() { $(this).on("click", function() { $(this).find("input")[0].click(); }); }); } function showSwitchArea(type) { swal({ closeOnClickOutside: false, title: "请输入要转换的key:", content: $('')[0], buttons: { confirm: "转换", back: "返回", cancel: "关闭" } }).then((value) => { if (value === "back") { showSwitchKey(); } else if (value) { const inputKey = $(".swal-content textarea").val(); if (inputKey) { switchKey(inputKey, 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: $(``)[0], buttons: { confirm: "返回", cancel: "关闭" } }).then((value) => { if (value) { showSwitchArea(type); } }); $(".swal-content textarea").on("click", function() { this.select(); }); } function getKeysByRE(text) { text = text.trim().toUpperCase(); const reg = new RegExp("([0-9A-Z]{5}-){2,4}[0-9A-Z]{5}", "g"); const keys = []; let result; while (result = reg.exec(text)) { keys.push(result[0]); } return keys; } // steamWeb.ts var STEAM_HOSTS = { STORE: "store.steampowered.com", LOGIN: "login.steampowered.com" }; var handleError = (error, message) => { console.error(`${message}:`, error); return false; }; async function refreshToken() { try { const formData = new FormData(); formData.append("redir", `https://${STEAM_HOSTS.STORE}/`); const response = await httpRequest({ url: `https://${STEAM_HOSTS.LOGIN}/jwt/ajaxrefresh`, method: "POST", responseType: "json", headers: { Host: STEAM_HOSTS.LOGIN, Origin: `https://${STEAM_HOSTS.STORE}`, Referer: `https://${STEAM_HOSTS.STORE}/` }, data: formData }); if (response.result === "Success" && response.data?.response?.success) { return await setStoreToken(response.data.response); } return false; } catch (error) { return handleError(error, "Failed to refresh token"); } } async function setStoreToken(param) { try { const host = "store.steampowered.com"; const formData = new FormData(); formData.append("steamID", param.steamID); formData.append("nonce", param.nonce); formData.append("redir", param.redir); formData.append("auth", param.auth); const { result, statusText, status, data } = await httpRequest({ url: `https://${host}/login/settoken`, method: "POST", headers: { Accept: "application/json, text/plain, */*", Host: host, Origin: `https://${host}` // Referer: `https://${host}/login` }, data: formData }); if (result === "Success") { if (data?.status === 200) { return true; } return false; } return false; } catch (error) { console.error(error); return false; } } async function updateStoreAuth(retry = false) { try { const { result, statusText, status, data } = await httpRequest({ url: "https://store.steampowered.com/", method: "GET", headers: { Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", "Cache-Control": "max-age=0", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Upgrade-Insecure-Requests": "1" }, fetch: false, redirect: "manual" }); if (data?.status === 200) { if (!data.responseText.includes("data-miniprofile=")) { if (await refreshToken()) { if (retry) { return false; } return updateStoreAuth(true); } return false; } const storeSessionID = data.responseText.match(/g_sessionID = "(.+?)";/)?.[1]; if (storeSessionID) { globalThis.sessionID = storeSessionID; return true; } return false; } if ([301, 302].includes(data?.status)) { if (await refreshToken()) { if (retry) { return false; } return updateStoreAuth(true); } return false; } return false; } catch (error) { console.error(error); return false; } } var showSwalMessage = (options) => { return swal({ className: "swal-user", closeOnClickOutside: false, ...options }); }; function webRedeem(key) { const redeemContent = createRedeemContent(); showSwalMessage({ title: "正在获取sessionID...", buttons: { confirm: "关闭" } }); if (!globalThis.sessionID) { handleNoSession(key, redeemContent); return; } showRedeemDialog(key, redeemContent); } function createRedeemContent() { return $(`
未使用的Key:

    激活记录

    No.Key结果详情Sub

    `)[0]; } function handleNoSession(key, redeemContent) { GM_xmlhttpRequest({ method: "GET", url: "https://store.steampowered.com/account/registerkey", onload: async (data) => { if (data.finalUrl.includes("login") && !await updateStoreAuth()) { showSwalMessage({ title: "请先登录steam!", icon: "warning", buttons: { confirm: "登录", cancel: "关闭" } }).then((value) => { if (value) window.open("https://store.steampowered.com/login/", "_blank"); }); } else { if (data.status === 200) { globalThis.sessionID = data.responseText?.match(/g_sessionID = "(.+?)";/)?.[1] || ""; showRedeemDialog(key, redeemContent); } else { showSwalMessage({ title: "获取sessionID失败!", icon: "error", buttons: { confirm: "关闭" } }); } } } }); } function showRedeemDialog(key, redeemContent) { showSwalMessage({ title: "正在激活steam key...", content: redeemContent, buttons: { confirm: "提取未使用key", cancel: "关闭" } }).then((v) => { let value = ""; const textarea = $(".swal-content textarea"); if (textarea.length > 0) { value = textarea.val()?.toString() || ""; } GM_setValue("history", [$(".swal-content").html() || "", value]); if (v) { GM_setClipboard(arr(getKeysByRE($("#unusedKeys").text() || "")).join(",")); showSwalMessage({ title: "复制成功!", icon: "success" }); } }); redeemKeys(key); } function redeemSub(e) { const subText = e || $("#gameSub").val(); if (subText) { const ownedPackages = {}; $(".account_table a").each((i, el) => { const match = el.href.match(/javascript:RemoveFreeLicense\( ([0-9]+), '/); if (match !== null) { ownedPackages[+match[1]] = true; } }); const freePackages = subText.match(/[\d]{2,}/g) || []; let loaded = 0; const total = freePackages.length; swal("正在执行…", "请等待所有请求完成。 忽略所有错误,让它完成。"); freePackages.forEach((packae) => { const packageId = parseInt(packae, 10); if (ownedPackages[packageId]) { loaded++; return; } $.post("//store.steampowered.com/checkout/addfreelicense", { action: "add_to_cart", sessionid: g_sessionID, subid: packageId }).always(() => { loaded++; if (loaded >= total) { if (window.location.href.includes("licenses")) { window.open("https://store.steampowered.com/account/licenses/", "_self"); } else { swal("全部激活完成,是否前往账户页面查看结果?", { //@ts-ignore buttons: { cancel: "取消", 确定: true } }).then((value) => { if (value) { window.open("https://store.steampowered.com/account/licenses/", "_blank"); } }); } } else { swal("正在激活…", `进度:${loaded}/${total}.`); } }); }); } } function redeemSubs() { const key = $("#inputKey").val()?.trim(); if (key) { redeemSub(key); } } async function cc() { try { showSwalMessage({ title: "正在获取当前国家/地区...", icon: "info" }); const cartData = await fetchCartData(); const { cartConfig, userInfo } = parseCartData(cartData); if (!isValidCartConfig(cartConfig, userInfo)) { showSwalMessage({ title: "需要挂相应地区的梯子!", icon: "warning" }); return; } showCountryChangeDialog(cartConfig, userInfo, cartData); } catch (error) { showSwalMessage({ title: "获取当前国家/地区失败!", icon: "error" }); } } function fetchCartData() { return new Promise((resolve, reject) => { $.ajax({ url: "//store.steampowered.com/cart/", type: "get", success: (data) => resolve(data), error: reject }); }); } function parseCartData(data) { const cartConfigRaw = data.match(/data-cart_config="(.*?)"/)?.[1]; const temp = document.createElement("div"); temp.innerHTML = cartConfigRaw || ""; const cartConfigStr = temp.textContent || temp.innerText || ""; try { const cartConfig = JSON.parse(cartConfigStr); if (!cartConfig || !cartConfig.rgUserCountryOptions) { throw new Error("Invalid cartConfig format"); } const userInfoRaw = data.match(/data-userinfo="(.*?)"/)?.[1]; const temp1 = document.createElement("div"); temp1.innerHTML = userInfoRaw || ""; const userInfoStr = temp1.textContent || temp1.innerText || ""; const userInfo = JSON.parse(userInfoStr); if (!userInfo || !userInfo.country_code) { throw new Error("Invalid userInfo format"); } return { cartConfig, userInfo }; } catch (e) { throw new Error("Failed to parse Steam data"); } } function isValidCartConfig(cartConfig, userInfo) { return cartConfig && userInfo && Object.keys(cartConfig.rgUserCountryOptions).length > 2; } function showCountryChangeDialog(cartConfig, userInfo, cartData) { const divContent = cartData.match(/
    ([\w\W]*?)

    `; showSwalMessage({ closeOnClickOutside: false, title: `当前国家/地区:${cartConfig.rgUserCountryOptions[userInfo.country_code] || userInfo.country_code}`, //@ts-ignore content: $(`

    ${div}
    `)[0] }).then(() => { $(".currency_change_option").click(function() { const country = $(this).attr("data-country"); if (country) { changeCountry(country); } }); }); } function changeCountry(country) { showSwalMessage({ closeOnClickOutside: false, icon: "info", title: "正在更换国家/地区..." }); $.ajax({ url: "//store.steampowered.com/country/setcountry", type: "post", data: { sessionid: g_sessionID, cc: country }, complete() { $.ajax({ url: "//store.steampowered.com/cart/", type: "get", success(data) { const cartConfigRaw = data.match(/data-cart_config="(.*?)"/)?.[1]; const temp = document.createElement("div"); temp.innerHTML = cartConfigRaw || ""; const cartConfigStr = temp.textContent || temp.innerText || ""; let cartConfig; try { cartConfig = JSON.parse(cartConfigStr); } catch (e) { console.error(e); showSwalMessage({ title: "获取当前国家/地区失败!", icon: "error" }); return; } const userInfoRaw = data.match(/data-userinfo="(.*?)"/)?.[1]; const temp1 = document.createElement("div"); temp1.innerHTML = userInfoRaw || ""; const userInfoStr = temp1.textContent || temp1.innerText || ""; let userInfo; try { userInfo = JSON.parse(userInfoStr); } catch (e) { console.error(e); showSwalMessage({ title: "获取当前国家/地区失败!", icon: "error" }); return; } const divContent = data.match(/
    ([\w\W]*?)

    `; if (userInfo?.country_code === country) { showSwalMessage({ title: "更换成功!", icon: "success" }).then(() => { showSwalMessage({ closeOnClickOutside: false, title: `当前国家/地区:${cartConfig?.rgUserCountryOptions[userInfo.country_code] || userInfo.country_code}`, //@ts-ignore content: $(`

    ${div}
    `)[0] }).then(() => { $(".currency_change_option").click(function() { const newCountry = $(this).attr("data-country"); if (newCountry) { changeCountry(newCountry); } }); }); }); } else { showSwalMessage({ title: "更换失败!", icon: "error" }); } }, error: () => { showSwalMessage({ title: "获取当前国家/地区失败!", icon: "error" }); } }); } }); } // redeem.ts var FAILURE_DETAILS = { 14: "无效激活码", 15: "重复激活", 53: "次数上限", 13: "地区限制", 9: "已拥有", 24: "缺少主游戏", 36: "需要PS3?", 50: "这是充值码" }; var UNUSED_KEY_REASONS = [ "次数上限", "地区限制", "已拥有", "缺少主游戏", "其他错误", "未知错误", "网络错误或超时" ]; 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=${globalThis.sessionID}`, method: "POST", responseType: "json", onloadstart() { if ($(globalThis.selecter + "table").is(":hidden")) { $(globalThis.selecter + "table").fadeIn(); } }, onload(response) { if (response.status === 200 && response.response) { const data = response.response; if (data.success === 1 && data.purchase_receipt_info?.line_items[0]) { const item = data.purchase_receipt_info.line_items[0]; tableUpdateKey( key, globalThis.myTexts.success, globalThis.myTexts.line, item.packageid, item.line_item_description ); return; } else if (data.purchase_result_details !== void 0 && data.purchase_receipt_info) { const item = data.purchase_receipt_info.line_items[0]; const failureReason = FAILURE_DETAILS[data.purchase_result_details] || globalThis.myTexts.others; if (!item) { tableUpdateKey( key, globalThis.myTexts.fail, failureReason, 0, globalThis.myTexts.nothing ); } else { tableUpdateKey( key, globalThis.myTexts.fail, failureReason, item.packageid, item.line_item_description ); } return; } tableUpdateKey(key, globalThis.myTexts.fail, globalThis.myTexts.nothing, 0, globalThis.myTexts.nothing); } else { tableUpdateKey(key, globalThis.myTexts.fail, globalThis.myTexts.network, 0, globalThis.myTexts.nothing); } }, ontimeout: () => { tableUpdateKey(key, globalThis.myTexts.fail, globalThis.myTexts.network, 0, globalThis.myTexts.nothing); }, onerror: () => { tableUpdateKey(key, globalThis.myTexts.fail, globalThis.myTexts.network, 0, globalThis.myTexts.nothing); }, onabort: () => { tableUpdateKey(key, globalThis.myTexts.fail, globalThis.myTexts.network, 0, globalThis.myTexts.nothing); } }); } function setUnusedKeys(key, success, reason, subId, subName) { if (success && globalThis.allUnusedKeys.includes(key)) { let listObject; globalThis.allUnusedKeys = globalThis.allUnusedKeys.filter((keyItem) => keyItem !== key); $(`${globalThis.selecter}li`).each((i, e) => { if ($(e).html()?.includes(key)) { listObject = $(e); listObject.remove(); } }); } else if (!success && !globalThis.allUnusedKeys.includes(key) && UNUSED_KEY_REASONS.includes(reason)) { const listObject = $("
  1. "); listObject.html( `${key} (${reason}${subId !== 0 ? `: ${subId} ${subName}` : ""})` ); $("#unusedKeys").append(listObject); globalThis.allUnusedKeys.push(key); } } function tableInsertKey(key) { globalThis.keyCount++; const row = $(""); row.append(`${globalThis.keyCount}`); row.append(`${key}`); row.append(`${globalThis.myTexts.redeeming}...`); $(`${globalThis.selecter}tbody`).prepend(row); } function tableWaitKey(key) { globalThis.keyCount++; const row = $(""); row.append(`${globalThis.keyCount}`); row.append(`${key}`); row.append(`${globalThis.myTexts.waiting} (${globalThis.waitingSeconds}秒)...`); $(`${globalThis.selecter}tbody`).prepend(row); } function tableUpdateKey(key, result, detail, subId, subName) { setUnusedKeys(key, result === globalThis.myTexts.success, detail, subId, subName); globalThis.recvCount++; if (!globalThis.selecter && globalThis.recvCount === globalThis.keyCount) { $("#buttonRedeem").fadeIn(); $("#inputKey").removeAttr("disabled"); } const rowObjects = $(`${globalThis.selecter}tr`); for (let i = 1; i < rowObjects.length; i++) { const rowElement = rowObjects[i]; const rowObject = $(rowElement); if (rowObject.children()[1].innerHTML.includes(key) && rowObject.children()[2].innerHTML.includes(globalThis.myTexts.redeeming)) { rowObject.children()[2].remove(); if (result === globalThis.myTexts.fail) { rowObject.append(`${result}`); } else { rowObject.append(`${result}`); } rowObject.append(`${detail}`); if (subId === 0) { rowObject.append("——"); } else { rowObject.append( `${subId} ${subName}` ); } break; } } } function startTimer() { const timer = setInterval(() => { let flag = false; let nowKey = 0; const rowObjects = $(`${globalThis.selecter}tr`); for (let i = rowObjects.length - 1; i >= 1; i--) { const rowElement = rowObjects[i]; const rowObject = $(rowElement); const cellContent = rowObject.children()[2]?.innerHTML; if (cellContent?.includes(globalThis.myTexts.waiting)) { nowKey++; if (nowKey <= globalThis.autoDivideNum) { let key = rowObject.children()[1]?.innerHTML.substring(6); key = key?.substring(0, key.indexOf("")) || ""; rowObject.children()[2].innerHTML = `${globalThis.myTexts.redeeming}...`; redeemKey(key); } else { flag = true; break; } } } if (!flag) { clearInterval(timer); } }, 1e3 * globalThis.waitingSeconds); } function redeem(keys) { if (keys.length <= 0) { return; } if (!globalThis.selecter) { $("#buttonRedeem").hide(); $("#inputKey").attr("disabled", "disabled"); } let nowKey = 0; keys.forEach((key) => { nowKey++; if (nowKey <= globalThis.autoDivideNum) { tableInsertKey(key); redeemKey(key); } else { tableWaitKey(key); } }); if (nowKey > globalThis.autoDivideNum) { startTimer(); } } function redeemKeys(key) { const keys = key ? key.split(",") : getKeysByRE($("#inputKey").val()?.toString()?.trim() || ""); redeem(keys); } function toggleUnusedKeyArea() { if (!globalThis.selecter) { const unusedKeyArea = $("#unusedKeyArea"); if (unusedKeyArea.is(":hidden")) { unusedKeyArea.show(); } else { unusedKeyArea.hide(); } } } function registerkey(key) { const setting = GM_getValue("setting"); const keys = getKeysByRE(key); if (setting?.asf) { const asfCommand = `!redeem ${setting.asfBot ? `${setting.asfBot} ` : ""}${keys.join(",")}`; asfRedeem(asfCommand); } else if (setting?.newTab) { const url = `https://store.steampowered.com/account/registerkey?key=${keys.join(",")}`; window.open(url, "_blank"); } else { webRedeem(keys.join(",")); } } // css.ts var css = `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; } table.hclonely caption { padding-top: 8px; color: #808294; text-align: center; caption-side: top; background-color: #94d7df; } table.hclonely h2 { margin: 0; font-size: 25px; } .swal-user { width: 80%; } table.hclonely a { color: #2196F3; } table.hclonely .swal-button { padding: 5px; } #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; } .swal-content *{ color:#000; } .swal-content textarea{ background: #fff; } #allKey{ display: inline-block; padding: 6px 12px; margin-bottom: 0; font-size: 14px; font-weight: 400; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-image: none; border: 1px solid transparent; border-radius: 4px;color: #333; background-color: #fff; border-color: #ccc; } #allKey:hover{ color: #333; background-color: #e6e6e6; border-color: #adadad; text-decoration: none; } #allKey:focus{ color: #333; background-color: #e6e6e6; border-color: #8c8c8c; text-decoration: none; } #allKey:active{ background-image: none; outline: 0; -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.125); box-shadow: inset 0 3px 5px rgba(0,0,0,.125);color: #333; background-color: #e6e6e6; border-color: #adadad; } .icon-img { position: absolute; width: 32px; height: 32px; margin: 0px!important; } .icon-div { width: 32px!important; height: 32px!important; display: none; background: #fff!important; border-radius: 16px!important; box-shadow: 4px 4px 8px #888!important; position: absolute!important; z-index: 2147483647!important; cursor: pointer; } `; // main.ts globalThis.url = window.location.href; globalThis.defaultSetting = { newTab: false, copyListen: true, selectListen: true, clickListen: true, allKeyListen: false, asf: false, asfProtocol: "http", asfHost: "127.0.0.1", asfPort: 1242, asfPassword: "", asfBot: "" }; globalThis.sessionID = ""; try { globalThis.sessionID = g_sessionID; } catch (e) { globalThis.sessionID = ""; } globalThis.allUnusedKeys = []; globalThis.selecter = globalThis.url.includes("/account/registerkey") ? "" : ".hclonely "; globalThis.myTexts = { fail: "失败", success: "成功", network: "网络错误或超时", line: "——", nothing: "", others: "其他错误", unknown: "未知错误", redeeming: "激活中", waiting: "等待中", showUnusedKey: "显示未使用的Key", hideUnusedKey: "隐藏未使用的Key" }; globalThis.autoDivideNum = 9; globalThis.waitingSeconds = 20; globalThis.keyCount = 0; globalThis.recvCount = 0; try { const setting = GM_getValue("setting"); if (Object.prototype.toString.call(setting) !== "[object Object]") { GM_setValue("setting", globalThis.defaultSetting); } if (setting?.selectListen) { const icon = document.createElement("div"); icon.className = "icon-div"; icon.title = "激活"; icon.innerHTML = `激活图标`; const $icon = $(icon); $("html").append(icon); $(document).mousedown((e) => { if (e.target === icon || e.target?.parentNode === icon || e.target?.parentNode?.parentNode === icon) { e.preventDefault(); } }); document.addEventListener("selectionchange", () => { if (!window.getSelection()?.toString()?.trim()) { $icon.hide(); } }); $(document).mouseup((e) => { if (e.target === icon || e.target?.parentNode === icon || e.target?.parentNode?.parentNode === icon) { e.preventDefault(); return false; } const text = window.getSelection()?.toString()?.trim(); const productKey = text || e.target?.value; if (/[\d\w]{5}(-[\d\w]{5}){2}/.test(productKey) && text && $icon.is(":hidden")) { $icon.css({ top: e.pageY + 12, left: e.pageX + 18 }).show(); } else if (!text) { $icon.hide(); } }); $icon.click((e) => { const productKey = window.getSelection()?.toString()?.trim() || e.target?.value; registerkey(productKey); }); } if (!/https?:\/\/store\.steampowered\.com\/account\/registerkey[\w\W]{0,}/.test(globalThis.url) && setting?.copyListen) { const activateProduct = async function(e) { const productKey = window.getSelection()?.toString()?.trim() || e.target?.value; const clipboardSuccess = await navigator.clipboard.writeText(productKey).then(() => true, () => false); if (/^([\w\W]*)?([\d\w]{5}(-[\d\w]{5}){2}(\r||,||,)?){1,}/.test(productKey)) { if (!$("div.swal-overlay").hasClass("swal-overlay--show-modal")) { swal({ title: "检测到神秘key,是否激活?", icon: "success", //@ts-ignore buttons: { confirm: "激活", cancel: "取消" } }).then((value) => { if (value) registerkey(productKey); }); } } else if (/^![\w\d]+\s+asf\s+.+/gi.test(productKey)) { if (setting?.asf && !$("div.swal-overlay").hasClass("swal-overlay--show-modal")) { swal({ closeOnClickOutside: false, className: "swal-user", title: "检测到您复制了以下ASF指令,是否执行?", text: productKey, //@ts-ignore buttons: { confirm: "执行", cancel: "取消" } }).then((value) => { if (value) asfRedeem(productKey); }); } } }; window.addEventListener("copy", activateProduct, false); } if (/^https?:\/\/store\.steampowered\.com\/account\/registerkey*/.test(globalThis.url)) { $("#registerkey_examples_text").html(`

    `); $("#copyUnuseKey").click(() => { const unusedKeys = $("#unusedKeys").text(); GM_setClipboard(arr(getKeysByRE(unusedKeys)).join(",")); swal({ title: "复制成功!", icon: "success" }); }); $(".registerkey_input_box_text").parent().css("float", "none").append(`
    `); if (/^https?:\/\/store\.steampowered\.com\/account\/registerkey\?key=.+/.test(globalThis.url)) { $("#inputKey").val(globalThis.url.replace(/https?:\/\/store\.steampowered\.com\/account\/registerkey\?key=/i, "")); } $(".registerkey_input_box_text,#purchase_confirm_ssa").hide(); $("#register_btn").parent().css("margin", "10px 0").append(` 激活key    激活sub    更换国家/地区   `); $("#register_btn").remove(); if (/^https?:\/\/store\.steampowered\.com\/account\/registerkey\?key=.+/.test(globalThis.url)) { redeem(getKeysByRE(globalThis.url.replace(/https?:\/\/store\.steampowered\.com\/account\/registerkey\?key=/i, "").trim())); } $("#redeemKey").click(() => { redeemKeys(); }); $("#redeemSub").click(redeemSubs); $("#changeCountry").click(cc); toggleUnusedKeyArea(); } else if (/https?:\/\/steamdb\.info\/freepackages\//.test(globalThis.url)) { const activateConsole = () => { const sub = []; $("#freepackages span:visible").each(function() { const subId = $(this).attr("data-subid"); if (subId) sub.push(subId); }); const freePackages = sub.join(","); window.open(`https://store.steampowered.com/account/licenses/?sub=${freePackages}`, "_self"); }; const fp = setInterval(() => { if ($("#freepackages").length > 0) { $("#freepackages").click(activateConsole); clearInterval(fp); } }, 1e3); } else if (/https?:\/\/store\.steampowered\.com\/account\/licenses\/(\?sub=[\w\W]{0,})?/.test(globalThis.url)) { $("h2.pageheader").parent().append(`
     
    激活SUB 更改国家/地区 `); $("#buttonSUB").click(() => { redeemSub(); }); $("#changeCountry-account").click(cc); if (/https?:\/\/store\.steampowered\.com\/account\/licenses\/\?sub=([\d]+,)+/.test(globalThis.url)) { setTimeout(() => { redeemSub(globalThis.url); }, 2e3); } } else if (setting?.clickListen) { let htmlEl = null; if ($("body").length > 0) { $("body").click((event) => { htmlEl = event.target; if ($(htmlEl).parents(".swal-overlay").length === 0 && !["A", "BUTTON", "TEXTAREA"].includes(htmlEl.tagName) && !["button", "text"].includes(htmlEl.getAttribute("type") || "") && ($(htmlEl).children().length === 0 || !/([0-9,A-Z]{5}-){2,4}[0-9,A-Z]{5}/gim.test($.makeArray($(htmlEl).children().map(function() { return $(this).text(); })).join(""))) && /([0-9,A-Z]{5}-){2,4}[0-9,A-Z]{5}/gim.test($(htmlEl).text())) { mouseClick($, event); arr($(htmlEl).text().match(/[\w\d]{5}(-[\w\d]{5}){2}/gim) || []).map((e) => { $(htmlEl).html($(htmlEl).html()?.replace(new RegExp(e, "gi"), `${e}`)); }); $(".redee-key").click(function() { registerkey($(this).attr("key") || ""); }); } }); } } if (/https?:\/\/store\.steampowered\.com\//.test(globalThis.url)) { $("#account_pulldown").before('更改国家/地区 |'); $("#changeCountry").click(cc); } if (setting?.allKeyListen) { redeemAllKey(); } GM_addStyle(css); GM_registerMenuCommand("⚙设置", settingChange); GM_registerMenuCommand("执行ASF指令", () => { asfSend(); }); } catch (e) { swal("AuTo Redeem Steamkey脚本执行出错,详情请查看控制台!", e.stack, "error"); console.error(e); }