// ==UserScript==
// @name 复制/清除/推送到青龙面板
// @version 1.7
// @description 提供清除、复制Cookies以及推送到青龙面板的功能,首次使用需进行测试和配置
// @author 翼城
// @match *://*/*
// @run-at document-end
// @grant GM_registerMenuCommand
// @grant GM_setClipboard
// @grant GM_xmlhttpRequest
// @grant GM_cookie
// @namespace
// @license MIT
// ==/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';
function clearAllCookies() {
let domain = window.location.hostname;
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=`;
});
alert('所有Cookie已被清除。');
}
function copyCookiesToClipboard() {
const cookies = document.cookie;
GM_setClipboard(cookies);
alert('Cookie已复制到剪贴板。');
}
async function testConnectionToPanel() {
if (isTested) {
if (confirm("配置已通过测试,是否需要重置配置?")) {
resetPanelConfiguration();
} else {
alert("当前配置已通过测试,无需重新输入。");
return;
}
}
const configInput = prompt("请输入面板配置,格式为:http://192.168.1.1:5700|Client_ID|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 = '9999';
container.style.maxHeight = '80vh';
container.style.overflowY = 'auto';
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 = '') {
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);
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);
});
}
})();