// ==UserScript==
// @name SillyTavern Auto Connect
// @namespace http://tampermonkey.net/
// @version 1.4
// @description 自动连接LLM API和AllTalkTTS API
// @match *://127.0.0.1:8000/*
// @license MIT
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @downloadURL https://update.greasyfork.icu/scripts/530465/SillyTavern%20Auto%20Connect.user.js
// @updateURL https://update.greasyfork.icu/scripts/530465/SillyTavern%20Auto%20Connect.meta.js
// ==/UserScript==
if (
window.location.href !== 'http://127.0.0.1:8000/' &&
!window.location.href.startsWith('http://127.0.0.1:8000/#')
) {
console.log('非目标页面,脚本终止');
return;
}
(function() {
'use strict';
// 配置中心
const CONFIG = {
buttons: [
{
selector: '#api_button_textgenerationwebui',
name: 'API连接',
status: {
element: '.online_status_indicator',
successCondition: el => el.classList.contains('success')
}
},
{
selector: '#tts_refresh',
name: 'TTS刷新',
status: {
element: '.at-settings-option.status-option #status_info',
successCondition: el => el.innerText.trim() === 'Ready'
}
}
],
timing: {
interval: 1000, // 检测间隔(ms),改为1.5秒加快检查速度
retryLimit: 30 // 最大尝试次数
}
};
// 获取界面显示设置,默认为显示(true)
let showInterface = GM_getValue('showInterface', true);
// 注册Tampermonkey菜单命令
function registerMenuCommands() {
GM_registerMenuCommand(`${showInterface ? '✓ 已启用' : '✗ 已禁用'} 界面显示`, () => {
showInterface = !showInterface;
GM_setValue('showInterface', showInterface);
// 如果面板已创建,则更新其显示状态
if (statusPanel) {
statusPanel.style.display = showInterface ? 'block' : 'none';
}
// 刷新菜单
registerMenuCommands();
});
}
// 初始注册菜单
registerMenuCommands();
// 创建增强状态面板
const statusPanel = createStatusPanel();
let isRunning = true;
// 状态面板模板
function createStatusPanel() {
const panel = document.createElement('div');
panel.style = `
position: fixed;
top: 20px;
right: 20px;
background: rgba(0,0,0,0.85);
color: white;
padding: 15px;
border-radius: 8px;
z-index: 99999;
font-family: Arial;
min-width: 220px;
backdrop-filter: blur(5px);
display: ${showInterface ? 'block' : 'none'};
`;
panel.innerHTML = `
`;
document.body.appendChild(panel);
// 添加停止按钮事件监听
panel.querySelector('#stopConnectBtn').addEventListener('click', () => {
isRunning = false;
const statusContent = panel.querySelector('#statusContent');
statusContent.innerHTML += `
已手动停止连接尝试
`;
// 3秒后关闭面板
setTimeout(() => {
statusPanel.remove();
}, 3000);
});
return panel;
}
// 状态检测器
function checkConnectionStatus(buttonConfig) {
const statusElement = document.querySelector(buttonConfig.status.element);
if (!statusElement) return false;
return buttonConfig.status.successCondition(statusElement);
}
// 增强点击方法
async function performEnhancedClick(selector) {
const btn = document.querySelector(selector);
if (!btn) return false;
// 使用更温和的方式触发点击,避免干扰用户操作
try {
// 直接调用按钮的原生click方法,而不是分发多个鼠标事件
btn.click();
await new Promise(resolve => setTimeout(resolve, 1000));
return true;
} catch (error) {
console.error(`点击按钮 ${selector} 时出错:`, error);
return false;
}
}
// 更新状态显示
function updateStatusDisplay(attempts) {
const statusContent = statusPanel.querySelector('#statusContent');
let html = CONFIG.buttons.map(btn => {
const isConnected = checkConnectionStatus(btn);
return `
${isConnected ? '✓' : '✗'}
${btn.name}:
${isConnected ? '已连接' : '未连接'}
`;
}).join('');
html += `
尝试次数:${attempts}/${CONFIG.timing.retryLimit}
下次检测:${new Date(Date.now() + CONFIG.timing.interval).toLocaleTimeString()}
`;
statusContent.innerHTML = html;
}
// 主控制器
async function controlLoop() {
let attempts = 0;
// 先检查是否已全部连接
let initialCheck = true;
let allConnected = true;
const connectionStatus = {};
// 检查每个按钮的连接状态
for (const btn of CONFIG.buttons) {
const isConnected = checkConnectionStatus(btn);
connectionStatus[btn.selector] = isConnected;
if (!isConnected) allConnected = false;
}
// 如果已全部连接,直接显示成功并3秒后关闭
if (allConnected) {
updateStatusDisplay(0);
const statusContent = statusPanel.querySelector('#statusContent');
statusContent.innerHTML += `
所有连接已成功!无需重连
`;
setTimeout(() => {
statusPanel.remove();
}, 3000);
return;
}
// 如果有未连接的,开始重连流程
const timer = setInterval(async () => {
if (!isRunning) {
clearInterval(timer);
return;
}
attempts++;
allConnected = true;
// 只对未连接的按钮进行点击操作
for (const btn of CONFIG.buttons) {
const isConnected = checkConnectionStatus(btn);
connectionStatus[btn.selector] = isConnected;
if (!isConnected) {
// 只点击未连接的按钮
const clicked = await performEnhancedClick(btn.selector);
if (!clicked) console.warn(`找不到按钮:${btn.name}`);
allConnected = false;
}
}
updateStatusDisplay(attempts);
if (allConnected || attempts >= CONFIG.timing.retryLimit) {
clearInterval(timer);
isRunning = false;
const statusContent = statusPanel.querySelector('#statusContent');
statusContent.innerHTML += `
${allConnected ? '所有连接已成功!' : '达到最大尝试次数'}
`;
// 添加3秒后移除面板逻辑
if (allConnected) {
setTimeout(() => {
statusPanel.remove();
}, 3000);
}
}
}, CONFIG.timing.interval);
}
// 启动系统
window.addEventListener('load', () => {
setTimeout(controlLoop, 2000); // 等待页面初始化
});
})();