Keylol Helper 提供其乐论坛多便捷功能支持,包括自动检测是否有其乐消息,
// ==UserScript== // @name Keylol Helper // @namespace http://tampermonkey.net/ // @version 0.2.8 // @description Keylol Helper 提供其乐论坛多便捷功能支持,包括自动检测是否有其乐消息, // @author shiquda // @namespace https://github.com/shiquda/shiquda_UserScript // @supportURL https://github.com/shiquda/shiquda_UserScript/issues // @match *://*/* // @icon https://keylol.com/favicon.ico // @grant GM_registerMenuCommand // @grant GM_xmlhttpRequest // @grant GM_notification // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @license AGPL-3.0 // ==/UserScript== (function () { 'use strict'; // 用户配置 const botID = "" // 指定的ASF bot名字 const message = "{:17_1010:}"// 自动回复要发送的信息,默认为阿鲁点赞 const checkInterval = 5; // 检测消息间隔,单位是分钟 const noticeTimeout = 10; // Win10/11通知显示时间,单位是秒 const featureInfo = [ '检测是否有其乐消息', '添加自动回复功能', '抽奖自动加愿望单', '快速跳转激活key', '检查是否已回贴' ] for (var i = 0; i < featureInfo.length; i++) { setMenu(featureInfo[i]) } checkNotice() if (isInKeylol()) { noticeAlert() } if (isInThread()) { addCSS() amIReplied() autoReply() keyGiving() addList() } if (isNotice()) { addNotice() } function setMenu(name) { const status = (GM_getValue(name) !== undefined) ? GM_getValue(name) : initialize(name); GM_registerMenuCommand(`${name}: ${status}`, () => { GM_setValue(name, !status); window.location.reload(); }); function initialize(name) { GM_setValue(name, true) return true } } // 判断是否在帖子页面 function isInThread() { const url = window.location.href; return (url.includes('https://keylol.com/t') || url.includes('https://keylol.com/forum.php?mod=viewthread')) } function isNotice() { const url = window.location.href return (url.includes('https://keylol.com/home.php?mod=space&do=notice')) } function isInKeylol() { const url = window.location.href return (url.includes('https://keylol.com')) } // 添加样式 function addCSS() { GM_addStyle(` .s_btn { display: inline-block; padding: 9px 8px; font-size: 20px; text-align: center; text-decoration: none; border-radius: 5px; background-color: #57b9e7; color: #FFFFFF; cursor: pointer; } .s_btn:hover { background-color: #0056b3; } .s_btn:active { background-color: #003d80; } .s_btn:focus { outline: none; box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.5); } } `) } // 添加自动回复功能 function autoReply() { if (!GM_getValue('添加自动回复功能')) return createUI1() function post() { document.querySelector("#post_reply").click() setTimeout(() => { document.querySelector("#postmessage").value = message }, 1000) setTimeout(() => { document.querySelector("#postsubmit").click(); }, 1050) } function createUI1() { var tab = document.querySelector("#pgt") var btn = document.createElement("button") btn.className = "s_btn" btn.textContent = "自动回帖" btn.title = `自动回复:${message}` btn.addEventListener("click", start) tab.appendChild(btn) } function start() { console.log("start") post() } } // 快速跳转激活key function keyGiving() { if (!GM_getValue('快速跳转激活key')) return if (document.querySelector(".subforum_left_title_left_up").innerText.indexOf("[明Key]") > -1) { const url = 'https://store.steampowered.com/account/registerkey' const tab = document.querySelector("#pgt") const container = document.createElement('button'); container.classList.add('s_btn'); container.textContent = '点击跳转到 Steam 激活页面'; container.addEventListener("click", () => { window.open(url) }) tab.appendChild(container) } } // 抽奖自动加愿望单 function addList() { if (!GM_getValue('抽奖自动加愿望单')) return if (judge()) { createUI2() } function judge() { return (document.querySelector(".subforum_left_title_left_up").innerText.indexOf("[活动推广]") > -1) } function getAppID(urls) { var AppIDs = [] if (urls.length === 0) { return AppIDs; // 如果urls数组为空,直接返回空数组 } for (var i = 0; i < urls.length; i++) { var AppID = urls[i].src.match(/^https:\/\/store\.steampowered\.com\/widget\/(\d+)/) if (AppID && AppID[1]) { AppIDs.push(AppID[1]) } } AppIDs = [...new Set(AppIDs)] return AppIDs } function createUI2() { let urls = document.querySelectorAll("iframe") const IDList = getAppID(urls) console.log(IDList) if (IDList.length === 0) { return } var txt = `ADDWISHLIST ${botID} `; for (var i = 0; i < IDList.length; i++) { txt += (IDList[i] + ",") } txt = txt.slice(0, -1) const tab = document.querySelector("#pgt") const container = document.createElement('button'); container.classList.add('s_btn'); container.textContent = '复制愿望单ASF代码'; container.addEventListener("click", () => { setCopy(txt, `ASF代码复制成功:${txt}`) }) tab.appendChild(container) } } // 检测是否有其乐消息 function checkNotice() { if (!GM_getValue('检测是否有其乐消息')) return let t = getBriefTime() var lastExecutionTimestamp = GM_getValue("lastExecutionTimestamp"); var currentTimestamp = new Date().getTime(); if ( !lastExecutionTimestamp || currentTimestamp - lastExecutionTimestamp > checkInterval * 60 * 1000 ) check() else { console.log(`${t} 时间间隔在${checkInterval}分钟内.`); return; } setTimeout(check, (checkInterval * 60 + 1) * 1000) function check() { let t = getBriefTime() GM_xmlhttpRequest({ method: "GET", url: "https://keylol.com/home.php?mod=space&do=notice", onload: function (response) { // 在响应中查找具有"btn-user-action-highlight"类的元素 var responseHTML = response.responseText; var parser = new DOMParser(); var doc = parser.parseFromString(responseHTML, "text/html"); var elements = doc.getElementsByClassName( "btn-user-action-highlight" ); if (elements.length > 0) { var newNotices = doc.querySelectorAll('[style="color:#000;font-weight:bold;"]') var noticeID = GM_getValue("noticeID") ? GM_getValue("noticeID") : [] for (var i = 0; i < newNotices.length; i++) { noticeID.push(newNotices[i].parentElement.getAttribute("notice")) } GM_setValue("noticeID", noticeID) GM_notification({ text: "点击前往", // 通知的文本内容 title: `Keylol有消息!`, // 通知的标题(可选) timeout: 1000 * noticeTimeout, // 通知显示的时间(毫秒),过了时间后通知会自动关闭(可选) onclick: function () { window.open( "https://keylol.com/home.php?mod=space&do=notice" ); }, }); } else { console.log(`${t} keylol没有通知.`); } }, onerror: function (error) { console.error(error); // 处理错误 }, }); GM_setValue("lastExecutionTimestamp", currentTimestamp); } function getBriefTime(d) { d = d ? new Date() : new Date(); // 获取小时、分钟和秒 let hours = d.getHours(); let minutes = d.getMinutes(); let seconds = d.getSeconds(); // 格式化小时、分钟和秒,确保它们始终是两位数 hours = (hours < 10 ? "0" : "") + hours; minutes = (minutes < 10 ? "0" : "") + minutes; seconds = (seconds < 10 ? "0" : "") + seconds; const currentTime = hours + ":" + minutes + ":" + seconds; // 返回当前时间 return currentTime; } } function noticeAlert() { if (!GM_getValue('检测是否有其乐消息')) return if (GM_getValue("noticeID")?.length > 0) { // console.log(GM_getValue("noticeID")) // 寻找提醒元素 const elements = document.querySelectorAll(".btn-user-action"); for (let i = 0; i < elements.length; i++) { const element = elements[i]; if (element.textContent.trim() === "提醒") { element.classList.add("btn-user-action-highlight") break } } } } function addNotice() { if (!GM_getValue('检测是否有其乐消息')) return const list = GM_getValue("noticeID") console.log(list); for (var i = 0; i < list.length; i++) { document.querySelector(`[notice="${list[i]}"]`).querySelector(".ntc_body").style = "color:#000;font-weight:bold;" } GM_setValue("noticeID", []) } // 检测帖子是否已回复 感谢@chr_ async function amIReplied() { "use strict"; if (!GM_getValue('检查是否已回贴')) return if ((location.pathname === "/forum.php" && !location.search.includes("tid")) || location.search.includes("authorid")) { return; } const inlineMode = window.localStorage.getItem("air_inline") ?? "关"; const isDiscuz = typeof discuz_uid != "undefined"; const userId = isDiscuz ? discuz_uid : __CURRENT_UID; const testUrl = location.href + (location.search ? `&authorid=${userId}` : `?authorid=${userId}`); fetch(testUrl) .then((res) => res.text()) .then((html) => { const replied = !(html.includes("未定义操作") || html.includes("ERROR:")); const text = replied ? "✅已经回过贴了" : "❌还没回过贴子"; const tips = document.createElement("a"); tips.textContent = text; if (replied) { tips.href = testUrl; } else { tips.addEventListener("click", () => { if (isDiscuz) { showError("❌还没回过贴子"); } else { alert("❌还没回过贴子"); } }); } if (isDiscuz) { const btnArea = inlineMode !== "开" ? document.querySelector("#pgt") : document.querySelector("#postlist td.plc div.authi>span.none") ?? document.querySelector("#postlist td.plc div.authi>span.pipe"); if (btnArea === null) { return; } if (btnArea.tagName === "SPAN") { const span = document.createElement("span"); span.textContent = "|"; span.className = "pipe"; const bar = btnArea.parentNode; bar.insertBefore(span, btnArea); bar.insertBefore(tips, btnArea); } else { btnArea.appendChild(tips); } } else { const btnArea = document.querySelector("#m_nav>.nav"); const anchor = btnArea.querySelector("div.clear"); if (btnArea === null || anchor === null) { return; } tips.className = "nav_link"; btnArea.insertBefore(tips, anchor); } }); } } )();