您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Make !addlicense commands clickable.
// ==UserScript== // @name ASF AddLicense Helper // @description Make !addlicense commands clickable. // @version 0.1.6 // @namespace Lex@GreasyFork // @author Lex // @match *://*.steamgifts.com/discussion/* // @match *://*.reddit.com/r/FreeGamesOnSteam/comments/* // @match *://*.reddit.com/r/FreeGameFindings/comments/* // @match *://steam.madjoki.com/apps/free // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @connect 127.0.0.1 // ==/UserScript== (function() { /* Configure Custom Server or Password */ let ASF_SERVER = ""; // e.g. 127.0.0.1:1242 let ASF_PASSWORD = ""; // e.g. 123456 /* End Configuration */ // Promise wrapper for GM_xmlhttpRequest const Request = details => new Promise((resolve, reject) => { details.onerror = details.ontimeout = reject; details.onload = resolve; GM_xmlhttpRequest(details); }); async function sendASF(command) { if (Array.isArray(command)) command = command.filter(e => e !== undefined).join(" "); const ASF_URL = "http://" + ASF_SERVER + "/Api/Command"; return await Request({ method: "POST", url: ASF_URL, headers: { "Content-Type": "application/json", accept: "application/json", Authentication: ASF_PASSWORD, }, data: JSON.stringify({ COMMAND: command, }), }); } async function addLicenseClick(event) { const el = event.target; el.style.textDecoration = ""; el.style.cursor = ""; el.style.color = "inherit"; el.onclick = undefined; console.log("Executing " + el.dataset.asfcommand); const resp = await sendASF(el.dataset.asfcommand); const indicator = document.createElement("span"); if (resp.responseText.includes("Status: OK")) { indicator.innerText = "✔️"; indicator.title = "Successfully added"; } else { indicator.innerText = "❗"; indicator.title = "Error adding license. See console for more info"; console.log(resp.responseText); } el.after(indicator); return false; } // https://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page function textNodesUnder(el){ let n, a=[], walk=document.createTreeWalker(el,NodeFilter.SHOW_TEXT,null,false); while(n=walk.nextNode()) a.push(n); return a; } function findCommands(ps) { const addreg = /\!addlicense\s+ASF\s+([as]\/\d+|sub\/\d+|app\/\d+|\d+)(?:,\s*([as]\/\d+|sub\/\d+|app\/\d+|\d+))*/gi; ps.forEach(p => { if (!p.innerText.includes("!addlicense")) return; textNodesUnder(p).forEach(node => { const ms = node.textContent.matchAll(addreg); for (const m of ms) { // tail contains any remaining text after the ASF command const tail = node.textContent.substring(m.index + m[0].length); // truncate the existing text node at the start of the ASF command node.textContent = node.textContent.substring(0, m.index); // full ASF command const cmd = m[0].trim(); const a = document.createElement("span"); a.style = "color:#4B72D4; background-color:inherit; cursor: pointer; text-decoration: underline; border:0;margin:0;padding:0;display:inline;text-align:inherit;" a.dataset.asfcommand = cmd; a.innerText = cmd; a.onclick = addLicenseClick; node.after(a); // if text was present after the ASF command, append it as a new text node if (tail !== "") { a.after(document.createTextNode(tail)); } } }) }); } // Handles loading and storing of custom settings function CustomSettings() { if (ASF_PASSWORD !== "") { GM_setValue("asf_password", ASF_PASSWORD); } else { ASF_PASSWORD = GM_getValue("asf_password", ""); } if (ASF_SERVER !== "") { GM_setValue("asf_server", ASF_SERVER); } else { ASF_SERVER = GM_getValue("asf_server", "127.0.0.1:1242"); } } CustomSettings(); if (/steamgifts\.com/.test(location.href)) { const ps = document.querySelectorAll(".markdown > *"); findCommands(ps); } if (/reddit\.com/.test(location.href)) { // Reddit does some late styling that will overwrite our changes, so we have to load even later setTimeout(function(){ const ps = document.querySelectorAll("[class*=RichTextJSON-root]"); findCommands(ps); }, 2000); } if (/steam\.madjoki\.com\/apps\/free/.test(location.href)) { const cmd = document.querySelector("[placeholder='!addlicense']").value; const add_asf_div = document.getElementById("add_asf"); const a = document.createElement("span"); a.style = "color:#4B72D4; background-color:inherit; cursor: pointer; text-decoration: underline; border:0;margin:0;padding:0;display:inline;text-align:inherit;"; a.dataset.asfcommand = cmd; a.innerText = cmd; a.onclick = addLicenseClick; add_asf_div.append(a); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址