您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
提供清除、复制Cookies以及推送到青龙面板的功能,首次使用需进行测试和配置
// ==UserScript== // @name 复制/清除/推送页面Cookies到青龙面板 // @version 3.10 // @description 提供清除、复制Cookies以及推送到青龙面板的功能,首次使用需进行测试和配置 // @author 翼城 // @match *://*/* // @run-at document-end // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setClipboard // @grant GM_xmlhttpRequest // @grant GM_cookie // @namespace // @license MIT // @namespace // @namespace // @namespace // ==/UserScript== (function () { "use strict"; let URL_HOST = localStorage.getItem("PANEL_URL_HOST") || ""; let Client_ID = localStorage.getItem("PANEL_Client_ID") || ""; let Client_Secret = localStorage.getItem("PANEL_Client_Secret") || ""; let isTested = localStorage.getItem("isTested") === "true"; let domain = window.location.hostname; async function clearCookies() { if (domain.split(".").length > 2) { domain = "." + domain.split(".").slice(-2).join("."); } const cookieNames = document.cookie.match(/[^ =;]+(?=\=)/g) || []; cookieNames.forEach((cookieName) => { document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=${domain}`; document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=`; }); } async function clearAllCookies() { await clearCookies(); alert("所有Cookie已被清除。"); } async function copyCookiesToClipboard() { const cookies = document.cookie; GM_setClipboard(cookies); alert("Cookie已复制到剪贴板。"); } async function testConnectionToPanel() { if (isTested) { if (confirm("配置已通过测试,是否需要重置配置?")) { resetPanelConfiguration(); } else { return; } } const configInput = prompt( "请输入面板配置,格式为:(面板ip:端口|your_Client_ID|your_Client_Secret)", `${URL_HOST}|${Client_ID}|${Client_Secret}`, ); if (!configInput) { alert("配置输入不能为空!"); return; } const configParts = configInput.split("|"); if (configParts.length !== 3) { alert("输入格式不正确,请按格式:面板地址|Client_ID|Client_Secret"); return; } [URL_HOST, Client_ID, Client_Secret] = configParts; try { let rr = await GM_fetch({ method: "GET", url: `${URL_HOST}/open/auth/token?client_id=${Client_ID}&client_secret=${Client_Secret}`, headers: { "content-type": "application/json", }, }); if (rr.status === 200) { let panel_token = JSON.parse(rr.responseText).data.token; alert("面板连接成功,Token获取正常!"); localStorage.setItem("PANEL_URL_HOST", URL_HOST); localStorage.setItem("PANEL_Client_ID", Client_ID); localStorage.setItem("PANEL_Client_Secret", Client_Secret); localStorage.setItem("isTested", "true"); isTested = true; } else { alert(`面板连接失败,状态码:${rr.status},错误信息:${rr.statusText}`); } } catch (error) { alert("面板连接失败,请检查面板地址、Client_ID和Client_Secret是否正确!"); } } function resetPanelConfiguration() { localStorage.removeItem("PANEL_URL_HOST"); localStorage.removeItem("PANEL_Client_ID"); localStorage.removeItem("PANEL_Client_Secret"); localStorage.removeItem("isTested"); URL_HOST = ""; Client_ID = ""; Client_Secret = ""; isTested = false; alert("面板配置已重置,请重新进行配置!"); } async function pushCookiesToPanel2() { if (!isTested) { alert("请先进行测试连接,以确保面板连接正常!"); return; } let ENV_NAME = prompt("请输入推送到面板的变量名", "COOKIES"); if (ENV_NAME === null) { return; } if (!ENV_NAME) { alert("变量名不能为空,请重新输入!"); return; } let collectedCookies = ""; let ready = setInterval(function () { GM_cookie.list({}, function (cookies, error) { if (!error) { for (let i = 0; i < cookies.length; i++) { collectedCookies += `${cookies[i].name}=${cookies[i].value};`; } if (collectedCookies !== "") { clearInterval(ready); getTokenAndPush(collectedCookies, ENV_NAME); } } else { console.error("获取Cookie时出错:", error); } }); }, 1000); } async function getTokenAndPush(cookies, ENV_NAME) { try { let rr = await GM_fetch({ method: "GET", url: `${URL_HOST}/open/auth/token?client_id=${Client_ID}&client_secret=${Client_Secret}`, headers: { "content-type": "application/json", }, }); if (rr.status === 200) { let panel_token = JSON.parse(rr.responseText).data.token; let res = await GM_fetch({ method: "GET", url: `${URL_HOST}/open/envs?searchValue=${ENV_NAME}`, headers: { "content-type": "application/json", Authorization: `Bearer ${panel_token}`, }, }); if (res.status === 200) { let id = JSON.parse(res.responseText).data[0].id; let ress = await GM_fetch({ method: "PUT", url: `${URL_HOST}/open/envs`, headers: { "content-type": "application/json", Authorization: `Bearer ${panel_token}`, }, data: JSON.stringify({ id: id, name: ENV_NAME, value: cookies }), }); if (ress.status === 200) { alert("Cookie已成功推送到面板!"); } else { alert( `推送Cookie失败,状态码:${ress.status},错误信息:${ress.statusText}`, ); console.error("推送Cookie失败:", ress); } } else { alert( `无法获取面板的环境变量列表,状态码:${res.status},错误信息:${res.statusText}`, ); } } else { alert( `无法获取面板Token,状态码:${rr.status},错误信息:${rr.statusText}`, ); } } catch (error) { alert( `大概率找不到变量名,确认青龙是否有。根据变量名自动创建功能,自己根据api写去吧!`, ); } } async function splitAndSelectCookies() { const cookies = document.cookie.split(";").map((cookie) => cookie.trim()); const container = document.createElement("div"); container.style.position = "fixed"; container.style.top = "20px"; container.style.right = "20px"; container.style.backgroundColor = "#ffffff"; container.style.border = "2px solid #ddd"; container.style.padding = "15px"; container.style.boxShadow = "0 0 10px rgba(0, 0, 0, 0.2)"; container.style.borderRadius = "8px"; container.style.zIndex = "10000"; container.style.maxHeight = "80vh"; container.style.overflowY = "auto"; // container.style.z-index = '10000'; const selectedCookies = new Set(); const pushButton = document.createElement("button"); pushButton.textContent = "推送Cookie到面板"; styleButton(pushButton, "#007bff", "#ffffff"); pushButton.onclick = () => { const selectedCookieValue = Array.from(selectedCookies).join(";"); promptAndPushCookies(selectedCookieValue); }; container.appendChild(pushButton); const confirmButton = document.createElement("button"); confirmButton.textContent = "保留选定的Cookie"; styleButton(confirmButton, "#28a745", "#ffffff"); confirmButton.onclick = () => { if (selectedCookies && selectedCookies.size == 0) { alert("请至少选择一个Cookie进行保留!"); return; } const finalCookies = Array.from(selectedCookies).join(";"); GM_setClipboard(finalCookies); alert("选定的Cookie已复制到剪贴板。"); document.body.removeChild(container); }; container.appendChild(confirmButton); const selectAllButton = document.createElement("button"); selectAllButton.textContent = "全选"; styleButton(selectAllButton, "#17a2b8", "#ffffff"); selectAllButton.onclick = () => { cookies.forEach((cookie) => { const button = document.getElementById(`cookie-button-${cookie}`); if (button && !button.classList.contains("selected")) { button.classList.add("selected"); selectedCookies.add(cookie); updateButtonStyle(button); } }); }; container.appendChild(selectAllButton); const toggleButton = document.createElement("button"); toggleButton.textContent = "反选"; styleButton(toggleButton, "#ffc107", "#ffffff"); toggleButton.onclick = () => { cookies.forEach((cookie) => { const button = document.getElementById(`cookie-button-${cookie}`); if (button) { button.classList.toggle("selected"); if (selectedCookies.has(cookie)) { selectedCookies.delete(cookie); } else { selectedCookies.add(cookie); } updateButtonStyle(button); } }); }; container.appendChild(toggleButton); const cancelButton = document.createElement("button"); cancelButton.textContent = "取消"; styleButton(cancelButton, "#dc3545", "#ffffff"); cancelButton.onclick = () => { document.body.removeChild(container); }; container.appendChild(cancelButton); cookies.forEach((cookie) => { const button = document.createElement("button"); button.textContent = cookie; button.id = `cookie-button-${cookie}`; button.style.display = "block"; button.style.marginBottom = "5px"; button.style.padding = "5px"; button.style.border = "1px solid #ccc"; button.style.backgroundColor = "#f0f0f0"; button.style.cursor = "pointer"; button.style.borderRadius = "5px"; button.onclick = () => { button.classList.toggle("selected"); if (selectedCookies.has(cookie)) { selectedCookies.delete(cookie); } else { selectedCookies.add(cookie); } updateButtonStyle(button); }; updateButtonStyle(button); container.appendChild(button); }); document.body.appendChild(container); } async function updateButtonStyle(button) { if (button.classList.contains("selected")) { button.style.backgroundColor = "#cce5ff"; button.style.color = "#004085"; button.style.border = "1px solid #004085"; } else { button.style.backgroundColor = "#f0f0f0"; button.style.color = "#000"; button.style.border = "1px solid #ccc"; } } async function styleButton(button, backgroundColor, color) { button.style.display = "block"; button.style.marginBottom = "10px"; button.style.padding = "8px 12px"; button.style.border = "none"; button.style.backgroundColor = backgroundColor; button.style.color = color; button.style.cursor = "pointer"; button.style.borderRadius = "5px"; button.style.fontSize = "14px"; button.style.fontWeight = "bold"; button.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.2)"; button.onmouseover = () => { button.style.opacity = "0.8"; }; button.onmouseout = () => { button.style.opacity = "1"; }; } async function promptAndPushCookies(defaultCookieValue = "") { if (!isTested) { alert("请先进行测试连接,以确保面板连接正常!"); return; } const ENV_NAME = prompt("请输入推送到面板的变量名", "COOKIES"); const cookieValue = prompt( "请输入推送到面板的 Cookie 值", defaultCookieValue, ); if (ENV_NAME === null || cookieValue === null) { return; } if (!ENV_NAME || !cookieValue) { alert("变量名 和 Cookie 值均不能为空,请重新输入!"); return; } getTokenAndPush(cookieValue, ENV_NAME); } /*GM_registerMenuCommand("清除所有Cookie", clearAllCookies); GM_registerMenuCommand("复制Cookie到剪贴板", copyCookiesToClipboard); GM_registerMenuCommand("青龙面板连接", testConnectionToPanel); GM_registerMenuCommand("选择性ck推送", splitAndSelectCookies); GM_registerMenuCommand('手动选择变量/值到面板', () => { promptAndPushCookies(); }); GM_registerMenuCommand("推送全部ck到面板", pushCookiesToPanel2); GM_registerMenuCommand("重置面板配置", resetPanelConfiguration);*/ if (window.self === window.top) { // 仅在主页面上运行 const existingButton = document.getElementById("menuButton"); if (!existingButton) { const style = document.createElement("style"); style.textContent = ` #customMenu { position: fixed; top: 50px; right: 10px; width: 220px; background: #ffffff; border: 1px solid #ddd; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); border-radius: 8px; z-index: 10000; display: none; overflow: hidden; transition: all 0.3s ease-in-out; } #customMenu button { display: block; width: 100%; border: none; background: #f9f9f9; padding: 12px; z-index: 10000; cursor: pointer; text-align: left; font-size: 16px; color: #333; transition: background 0.2s, color 0.2s; } #customMenu button:hover { background: #007bff; color: #fff; } #menuButton { position: fixed; top: 10px; right: 10px; width: 120px; height: 50px; background: #007bff; color: white; border: none; cursor: pointer; text-align: center; line-height: 50px; font-size: 16px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); z-index: 10000; transition: all 0.2s ease-in-out; } `; document.head.appendChild(style); const menuButton = document.createElement("button"); menuButton.id = "menuButton"; menuButton.textContent = "CK管理菜单"; document.body.appendChild(menuButton); const customMenu = document.createElement("div"); customMenu.id = "customMenu"; document.body.appendChild(customMenu); const menuItems = [ { name: "清除所有Cookie", action: clearAllCookies }, { name: "复制Cookie到剪贴板", action: copyCookiesToClipboard }, { name: "青龙面板连接", action: testConnectionToPanel }, { name: "选择部分ck推送", action: splitAndSelectCookies }, { name: "手动选择变量/值到面板", action: promptAndPushCookies }, { name: "推送全部ck到面板", action: pushCookiesToPanel2 }, { name: "替换cookie", action: replaceCookies }, { name: "重置面板配置", action: resetPanelConfiguration }, ]; menuItems.forEach((item) => { const button = document.createElement("button"); button.textContent = item.name; button.onclick = item.action; customMenu.appendChild(button); }); const isButtonHidden = localStorage.getItem("menuButtonHidden") === "true"; if (isButtonHidden) { menuButton.style.display = "none"; } let isMenuVisible = false; let menuCommandId = null; function updateMenuCommand() { const isHidden = menuButton.style.display === "none"; const statusSymbol = isHidden ? "❌" : "✅"; if (menuCommandId !== null) { GM_unregisterMenuCommand(menuCommandId); } menuCommandId = GM_registerMenuCommand( `${statusSymbol} 显示/隐藏 CK管理按钮`, toggleMenuButton, ); } function toggleMenuButton() { const isHidden = menuButton.style.display === "none"; menuButton.style.display = isHidden ? "block" : "none"; localStorage.setItem("menuButtonHidden", !isHidden); isMenuVisible = !isHidden; updateMenuCommand(); } updateMenuCommand(); menuButton.onclick = () => { isMenuVisible = !isMenuVisible; customMenu.style.display = isMenuVisible ? "block" : "none"; updateMenuCommand(); }; document.addEventListener("click", (event) => { if ( !menuButton.contains(event.target) && !customMenu.contains(event.target) ) { isMenuVisible = false; customMenu.style.display = "none"; updateMenuCommand(); } }); let isDragging = false; let offsetX, offsetY; let dragStartTime; const dragThreshold = 1000; menuButton.addEventListener("mousedown", (event) => { isDragging = true; dragStartTime = Date.now(); offsetX = event.clientX - menuButton.getBoundingClientRect().left; offsetY = event.clientY - menuButton.getBoundingClientRect().top; }); document.addEventListener("mousemove", (event) => { if (isDragging) { const newLeft = event.clientX - offsetX; const newTop = event.clientY - offsetY; menuButton.style.left = `${newLeft}px`; menuButton.style.top = `${newTop}px`; } }); document.addEventListener("mouseup", () => { if (isDragging) { isDragging = false; const dragDuration = Date.now() - dragStartTime; if (dragDuration < dragThreshold) { menuButton.click(); } snapToEdge(); } }); menuButton.addEventListener("touchstart", (event) => { isDragging = true; dragStartTime = Date.now(); const touch = event.touches[0]; offsetX = touch.clientX - menuButton.getBoundingClientRect().left; offsetY = touch.clientY - menuButton.getBoundingClientRect().top; }); document.addEventListener("touchmove", (event) => { if (isDragging) { const touch = event.touches[0]; const newLeft = touch.clientX - offsetX; const newTop = touch.clientY - offsetY; menuButton.style.left = `${newLeft}px`; menuButton.style.top = `${newTop}px`; } }); document.addEventListener("touchend", () => { if (isDragging) { isDragging = false; const dragDuration = Date.now() - dragStartTime; if (dragDuration < dragThreshold) { menuButton.click(); } snapToEdge(); } }); async function snapToEdge() { let newLeft; let position = menuButton.getBoundingClientRect(); if (window.innerWidth - position.right > position.left) { newLeft = 0; } else { newLeft = window.innerWidth - position.width; } menuButton.style.left = `${newLeft}px`; menuButton.style.transition = "all 0.2s ease-in-out"; if (isMenuVisible) { customMenu.style.display = "none"; isMenuVisible = false; updateMenuCommand(); } ensureVisibility(); } function ensureVisibility() { let position = menuButton.getBoundingClientRect(); if ( position.top < 0 || position.left < 0 || position.right > window.innerWidth || position.bottom > window.innerHeight ) { menuButton.style.top = "10px"; menuButton.style.left = `${ window.innerWidth - menuButton.offsetWidth - 10 }px`; } } ensureVisibility(); // const iframe = document.querySelector("iframe"); // iframe.onload = function () { // const iframeDocument = iframe.contentWindow.document; // const menuButton = iframeDocument.getElementById("menuButton"); // if (menuButton) { // menuButton.parentNode.removeChild(menuButton); // } // }; async function parseCookieString(ck) { return ck.split(";").map((e) => e.trim()); } } else { console.log("菜单按钮已存在,跳过创建。"); } } else { console.log("脚本在iframe内运行,跳过按钮创建。"); } async function replaceCookies() { let cookies = prompt("请输入cookie:"); cookies = await parseCookieString(cookies); if (cookies) { await clearCookies(); } cookies.forEach((e) => { document.cookie = e + ";domain=." + domain + ";path=/;"; }); location.reload(); } async function GM_fetch(details) { return new Promise((resolve, reject) => { details.onload = (res) => resolve(res); details.onerror = (res) => { alert(`请求出错:${res.statusText || "未知错误"}`); reject(res); }; details.ontimeout = (res) => { alert("请求超时!"); reject(res); }; details.onabort = (res) => { alert("请求被中止!"); reject(res); }; GM_xmlhttpRequest(details); }); } })();