// ==UserScript== // @name dcms论坛增强插件 // @namespace http://3g.cx/ // @version 3.5 // @description 为dcms论坛提供多种增强功能,提升用户体验,集成AI助手 // @author 42hz,pulana // @match https://3g.cx/* // @match http://3g.cx/* // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @run-at document-start // @require https://code.jquery.com/jquery-3.6.0.min.js // ==/UserScript== (function() { 'use strict'; // 初始化配置 function initializeConfig() { // 初始化默认配置 const defaultConfig = { apiUrl: 'https://apis.iflow.cn/v1/chat/completions', apiKey: '', customApiEnabled: false, modelId: 'tstars2.0', maxTokens: 512, temperature: 0.7, topP: 0.7, topK: 50, frequencyPenalty: 0.5, aiLongTermMemory: [], aiContext: [], aiMemoryLimit: 10, highlightOwn: true, hideOldMessages: false, autoRefreshChat: false, refreshInterval: 30, blockedUsers: [], nightMode: false }; if (GM_getValue('config', null) === null) { GM_setValue('config', defaultConfig); } } // 获取配置 function getConfig() { const config = GM_getValue('config', { apiUrl: 'https://apis.iflow.cn/v1/chat/completions', apiKey: '', customApiEnabled: false, modelId: 'tstars2.0', maxTokens: 512, temperature: 0.7, topP: 0.7, topK: 50, frequencyPenalty: 0.5, aiLongTermMemory: [], aiContext: [], aiMemoryLimit: 10, highlightOwn: true, hideOldMessages: false, autoRefreshChat: false, refreshInterval: 30, blockedUsers: [], nightMode: false }); // 确保数组字段存在 if (!Array.isArray(config.aiLongTermMemory)) { config.aiLongTermMemory = []; } if (!Array.isArray(config.aiContext)) { config.aiContext = []; } return config; } // 保存配置 function saveConfig(config) { GM_setValue('config', config); } // 检查jQuery是否已加载 function waitForJQuery() { if (typeof $ !== 'undefined') { initialize(); } else { setTimeout(waitForJQuery, 100); } } // 初始化脚本 function initialize() { initializeConfig(); // 添加全局样式 addGlobalStyles(); // 添加导航栏快捷功能 addQuickFeatures(); // 添加论坛页面增强功能 if (window.location.href.includes('/forum/')) { enhanceForum(); } // 添加聊天室增强功能 if (window.location.href.includes('/chat/')) { enhanceChat(); } // 添加日记页面增强功能 if (window.location.href.includes('/plugins/notes/')) { enhanceNotes(); } // 添加留言板增强功能 if (window.location.href.includes('/guest/')) { enhanceGuestbook(); } // 添加用户页面增强功能 if (window.location.href.includes('/user/info.php')) { enhanceUserProfile(); } // 添加快速搜索功能 addQuickSearch(); // 添加夜间模式切换 addNightMode(); // 添加一键清空浏览历史功能 addClearHistoryButton(); // 添加AI助手功能 addAIAssistant(); // 添加页面加载完成后的处理 $(document).ready(function() { // 应用已保存的设置 applySavedSettings(); // 添加页面特定功能 addPageSpecificFeatures(); }); } // 添加全局样式 function addGlobalStyles() { GM_addStyle(` /* 全局增强样式 */ .gm-enhancement-panel { background: #f0f0f0; border: 1px solid #ccc; padding: 10px; margin: 10px 0; border-radius: 5px; } .gm-btn { background: #007cba; color: white; border: none; padding: 5px 10px; margin: 0 2px; border-radius: 3px; cursor: pointer; font-size: 12px; } .gm-btn:hover { background: #005a87; } .gm-btn-danger { background: #d9534f; } .gm-btn-danger:hover { background: #c9302c; } .gm-btn-success { background: #5cb85c; } .gm-btn-success:hover { background: #449d44; } .gm-btn-warning { background: #f0ad4e; } .gm-btn-warning:hover { background: #ec971f; } .gm-btn-config { background: #5bc0de; } .gm-btn-config:hover { background: #31b0d5; } .gm-night-mode { background-color: #2c2c2c !important; color: #e0e0e0 !important; } .gm-night-mode a { color: #64b5f6 !important; } .gm-night-mode input, .gm-night-mode textarea { background-color: #424242 !important; color: #e0e0e0 !important; border: 1px solid #666 !important; } .gm-night-mode table { border-color: #666 !important; } .gm-night-mode .gm-enhancement-panel { background: #3c3c3c; border-color: #666; } .gm-quick-actions { position: fixed; bottom: 20px; right: 20px; z-index: 9999; } .gm-quick-action-btn { display: block; width: 40px; height: 40px; background: #007cba; color: white; border-radius: 50%; text-align: center; line-height: 40px; margin: 5px 0; text-decoration: none; box-shadow: 0 2px 10px rgba(0,0,0,0.3); cursor: pointer; } .gm-quick-action-btn:hover { background: #005a87; } .gm-search-box { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10000; background: white; padding: 15px; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.3); display: none; width: 90%; max-width: 500px; max-height: 80vh; overflow-y: auto; } .gm-night-mode .gm-search-box { background: #3c3c3c; color: #e0e0e0; } .gm-hidden-content { display: none !important; } .gm-highlighted { background-color: #e6f3ff !important; border: 2px solid #007cba !important; } .gm-night-mode .gm-highlighted { background-color: #1a237e !important; border: 2px solid #64b5f6 !important; } .gm-ai-assistant { position: fixed; bottom: 20px; left: 20px; z-index: 9999; width: 300px; background: white; border: 1px solid #ccc; border-radius: 8px; box-shadow: 0 4px 20px rgba(0,0,0,0.3); display: none; } .gm-night-mode .gm-ai-assistant { background: #3c3c3c; border-color: #666; } .gm-ai-header { background: #007cba; color: white; padding: 10px; border-radius: 8px 8px 0 0; cursor: move; } .gm-night-mode .gm-ai-header { background: #005a87; } .gm-ai-content { padding: 10px; max-height: 200px; overflow-y: auto; } .gm-ai-input { width: calc(100% - 20px); padding: 5px; margin: 10px 0; } .gm-ai-message { margin: 5px 0; padding: 5px; border-radius: 5px; } .gm-ai-user { background: #e6f3ff; text-align: right; } .gm-night-mode .gm-ai-user { background: #1a237e; } .gm-ai-assistant-response { background: #f0f0f0; } .gm-night-mode .gm-ai-assistant-response { background: #424242; } .gm-ai-typing { font-style: italic; color: #888; } .gm-night-mode .gm-ai-typing { color: #aaa; } .gm-api-error { color: #d9534f; font-weight: bold; } .gm-api-success { color: #5cb85c; font-weight: bold; } .gm-search-highlight { background-color: yellow !important; font-weight: bold; } .gm-ai-config-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border: 1px solid #ccc; border-radius: 8px; padding: 15px; margin: 10px 0; box-shadow: 0 4px 20px rgba(0,0,0,0.3); z-index: 10001; width: 90%; max-width: 400px; max-height: 80vh; overflow-y: auto; } .gm-night-mode .gm-ai-config-panel { background: #3c3c3c; border-color: #666; } .gm-ai-memory-item { padding: 5px; margin: 5px 0; border: 1px solid #ddd; border-radius: 3px; word-wrap: break-word; } .gm-night-mode .gm-ai-memory-item { border-color: #666; } .gm-ai-memory-controls { margin-top: 10px; padding-top: 10px; border-top: 1px solid #ddd; } .gm-night-mode .gm-ai-memory-controls { border-top: 1px solid #666; } .gm-ai-advanced-settings { margin: 10px 0; padding: 10px; border: 1px solid #ddd; border-radius: 5px; } .gm-night-mode .gm-ai-advanced-settings { border-color: #666; } .gm-ai-tool-call { background: #e8f4f8; border-left: 3px solid #007cba; padding: 5px; margin: 5px 0; font-size: 12px; } .gm-night-mode .gm-ai-tool-call { background: #1a237e; border-left: 3px solid #64b5f6; } `); } // 添加导航栏快捷功能 function addQuickFeatures() { $(document).ready(function() { // 添加快速导航按钮 if ($('.gm-enhancement-panel').length === 0) { const quickPanel = `
DCMS增强功能:
`; $('body').prepend(quickPanel); // 绑定快速导航事件 $('#gm-go-home').click(function() { window.location.href = '/'; }); $('#gm-go-forum').click(function() { window.location.href = '/forum/'; }); $('#gm-go-chat').click(function() { window.location.href = '/chat/'; }); $('#gm-go-notes').click(function() { window.location.href = '/plugins/notes/'; }); $('#gm-go-guest').click(function() { window.location.href = '/guest/'; }); $('#gm-go-downloads').click(function() { window.location.href = '/down/'; }); $('#gm-go-users').click(function() { window.location.href = '/user/users.php'; }); $('#gm-go-night-mode').click(function() { toggleNightMode(); }); $('#gm-go-settings').click(function() { showSettingsPanel(); }); $('#gm-go-ai-assistant').click(function() { toggleAIAssistant(); }); } }); } // 增强论坛页面功能 function enhanceForum() { $(document).ready(function() { const config = getConfig(); // 添加快速发帖按钮 const quickPostBtn = `
`; // 找到合适的插入位置 const container = $('body').find('table').first(); if (container.length > 0) { container.before(quickPostBtn); } else { $('body').prepend(quickPostBtn); } // 绑定事件 $('#gm-new-topic').click(function() { window.location.href = '/forum/new_t.php'; }); $('#gm-expand-all-posts').click(function() { // 展开所有帖子内容(模拟点击"»"链接) $('a:contains("»")').each(function() { if (!$(this).hasClass('gm-expanded')) { $(this).addClass('gm-expanded'); // 显示可能被隐藏的内容 $(this).closest('div').nextAll().show(); } }); }); $('#gm-collapse-all-posts').click(function() { $('.gm-expanded').removeClass('gm-expanded'); $('a:contains("»")').closest('div').nextAll().hide(); }); $('#gm-filter-by-user').click(function() { const username = $('#gm-user-filter-input').val(); if (username) { filterPostsByUser(username); } }); $('#gm-highlight-own').click(function() { config.highlightOwn = !config.highlightOwn; saveConfig(config); if (config.highlightOwn) { $(this).addClass('gm-btn-success'); highlightOwnPosts(); } else { $(this).removeClass('gm-btn-success'); $('.gm-highlighted').removeClass('gm-highlighted'); } }); // 添加帖子列表增强功能 addForumListEnhancements(); // 如果设置了自动高亮,应用它 if (config.highlightOwn) { setTimeout(highlightOwnPosts, 500); } }); } // 高亮自己的帖子 function highlightOwnPosts() { const username = getCurrentUsername(); if (username) { // 查找所有包含用户名的元素,并高亮其最近的容器 $('a, span, div, p').each(function() { if ($(this).text().includes(username) && !$(this).parents('.gm-hidden-content').length) { const container = $(this).closest('div, table, tr, p').first(); if (container.length > 0) { container.addClass('gm-highlighted'); } else { $(this).addClass('gm-highlighted'); } } }); } } // 获取当前用户名 function getCurrentUsername() { // 检查页面中可能包含用户名的元素 const usernamePatterns = [ // 检查退出按钮附近的用户名 $('a:contains("退出")').siblings('a').first(), // 检查顶部用户链接 $('a[href*="/user/info.php"]').first(), // 检查页面顶部的其他用户相关信息 $('.user-info a').first(), // 检查页面顶部导航 $('nav a[href*="/user/info.php"]').last() ]; for (let i = 0; i < usernamePatterns.length; i++) { if (usernamePatterns[i] && usernamePatterns[i].length > 0) { const text = usernamePatterns[i].text().trim(); if (text && text.length > 0 && text.length < 30 && !text.includes('用户') && !text.includes('退出') && !text.includes('登录') && !text.includes('注册')) { return text; } } } return null; } // 过滤特定用户的帖子 function filterPostsByUser(username) { // 先显示所有内容 $('.gm-hidden-content').removeClass('gm-hidden-content'); // 遍历所有可能包含帖子信息的容器 $('body').find('div, table, tr, p').each(function() { const elem = $(this); if (elem.text().includes(username)) { // 包含目标用户名,保留 elem.removeClass('gm-hidden-content'); } else { // 检查是否包含用户链接 let hasTargetUser = false; elem.find('a').each(function() { if ($(this).attr('href') && $(this).attr('href').includes('/user/info.php?id=')) { if ($(this).text().includes(username)) { hasTargetUser = true; } } }); if (!hasTargetUser) { elem.addClass('gm-hidden-content'); } else { elem.removeClass('gm-hidden-content'); } } }); } // 增强论坛列表页面 function addForumListEnhancements() { $(document).ready(function() { // 添加一键复制帖子链接功能 $('a[href*="/forum/"]').each(function() { if ($(this).attr('href').match(/\/forum\/\d+\/\d+\/\d+\//)) { const link = $(this).attr('href'); const postId = extractPostId(link); if (postId) { const copyBtn = ``; $(this).after(copyBtn); } } }); // 绑定复制链接事件 $(document).on('click', '.gm-copy-link', function() { const link = $(this).data('link'); navigator.clipboard.writeText(window.location.origin + link); alert('链接已复制到剪贴板!'); }); }); } // 提取帖子ID function extractPostId(url) { const match = url.match(/\/forum\/\d+\/\d+\/(\d+)\//); return match ? match[1] : null; } // 增强聊天室功能 function enhanceChat() { $(document).ready(function() { const config = getConfig(); // 添加聊天室增强功能 const chatEnhancement = `
聊天室增强功能:
`; $('body').prepend(chatEnhancement); // 绑定事件 $('#gm-chat-refresh').click(function() { location.reload(); }); $('#gm-chat-auto-refresh').click(function() { config.autoRefreshChat = !config.autoRefreshChat; saveConfig(config); if (config.autoRefreshChat) { $(this).addClass('gm-btn-success').text('停止刷新'); startAutoRefresh(); } else { $(this).removeClass('gm-btn-success').text('自动刷新'); stopAutoRefresh(); } }); $('#gm-chat-filter').click(function() { const keyword = $('#gm-chat-filter-input').val(); if (keyword) { filterChatMessages(keyword); } }); $('#gm-chat-highlight-own').click(function() { config.highlightOwn = !config.highlightOwn; saveConfig(config); if (config.highlightOwn) { $(this).addClass('gm-btn-success'); highlightOwnChatMessages(); } else { $(this).removeClass('gm-btn-success'); $('.gm-highlighted').removeClass('gm-highlighted'); } }); $('#gm-chat-hide-old').click(function() { config.hideOldMessages = !config.hideOldMessages; saveConfig(config); if (config.hideOldMessages) { $(this).addClass('gm-btn-success'); // 隐藏较早的消息(保留最新的50条) const allMessages = $('body').find('a[href*="/chat/room/"]').closest('div, p'); if (allMessages.length > 50) { allMessages.slice(0, allMessages.length - 50).addClass('gm-hidden-content'); } } else { $(this).removeClass('gm-btn-success'); $('.gm-hidden-content').removeClass('gm-hidden-content'); } }); // 如果开启了自动刷新,启动定时器 if (config.autoRefreshChat) { startAutoRefresh(); $('#gm-chat-auto-refresh').addClass('gm-btn-success').text('停止刷新'); } // 如果设置了自动高亮,应用它 if (config.highlightOwn) { setTimeout(highlightOwnChatMessages, 500); } }); } // 启动自动刷新 function startAutoRefresh() { const config = getConfig(); stopAutoRefresh(); // 先停止之前的定时器 window.chatRefreshInterval = setInterval(function() { location.reload(); }, config.refreshInterval * 1000); } // 停止自动刷新 function stopAutoRefresh() { if (window.chatRefreshInterval) { clearInterval(window.chatRefreshInterval); window.chatRefreshInterval = null; } } // 高亮聊天室中自己的消息 function highlightOwnChatMessages() { const username = getCurrentUsername(); if (username) { $('a, span, div, p').each(function() { if ($(this).text().includes(username) && !$(this).parents('.gm-hidden-content').length) { const container = $(this).closest('div, p').first(); if (container.length > 0) { container.addClass('gm-highlighted'); } else { $(this).addClass('gm-highlighted'); } } }); } } // 过滤聊天消息 function filterChatMessages(keyword) { // 先显示所有内容 $('.gm-hidden-content').removeClass('gm-hidden-content'); $('body').find('a, div, span, p').each(function() { if ($(this).text().toLowerCase().includes(keyword.toLowerCase())) { // 包含关键词的消息保留 $(this).closest('div, p').removeClass('gm-hidden-content'); } else { // 不包含关键词的消息隐藏 $(this).closest('div, p').addClass('gm-hidden-content'); } }); } // 增强日记页面功能 function enhanceNotes() { $(document).ready(function() { // 添加日记增强功能 const notesEnhancement = `
日记增强功能:
`; $('body').prepend(notesEnhancement); // 修正写日记按钮的链接 $('#gm-new-note').click(function() { window.location.href = '/plugins/notes/add.php'; }); // 绑定事件 $('#gm-notes-filter').click(function() { const user = $('#gm-notes-user-filter').val(); if (user) { filterNotesByUser(user); } }); $('#gm-notes-search').click(function() { const keyword = $('#gm-notes-search-input').val(); if (keyword) { searchNotes(keyword); } }); $('#gm-notes-highlight-own').click(function() { highlightOwnNotes(); }); }); } // 过滤指定用户的日记 function filterNotesByUser(username) { // 先显示所有内容 $('.gm-hidden-content').removeClass('gm-hidden-content'); // 为每个日志条目检查是否包含指定用户名 $('body').find('a').each(function() { const link = $(this); if (link.attr('href') && link.attr('href').includes('/user/info.php')) { if (link.text().includes(username)) { // 找到包含用户名的用户链接,显示其相关内容 const container = link.closest('div, p, table').first(); if (container.length > 0) { container.removeClass('gm-hidden-content'); } } else { // 不包含用户名的用户链接,检查是否需要隐藏 const container = link.closest('div, p, table').first(); if (container.length > 0) { container.addClass('gm-hidden-content'); } } } }); } // 搜索日记内容(页面内搜索) function searchNotes(keyword) { if (!keyword) return; // 先移除之前的高亮和隐藏 $('.gm-search-highlight').removeClass('gm-search-highlight'); $('.gm-hidden-content').removeClass('gm-hidden-content'); let foundAny = false; // 在页面中搜索关键词 $('body').find('a, div, p, span').each(function() { const element = $(this); const text = element.text(); if (text.toLowerCase().includes(keyword.toLowerCase())) { // 高亮包含关键词的元素 element.addClass('gm-search-highlight'); foundAny = true; // 确保包含关键词的容器可见 const container = element.closest('div, p, table'); if (container.length > 0) { container.removeClass('gm-hidden-content'); } } }); // 如果没有找到结果,显示提示 if (!foundAny) { alert(`未找到包含"${keyword}"的内容`); } } // 高亮自己的日记 function highlightOwnNotes() { const username = getCurrentUsername(); if (username) { $('body').find('a, span, div, p').each(function() { if ($(this).text().includes(username) && !$(this).parents('.gm-hidden-content').length && ($(this).closest('div, p').find('a[href*="/plugins/notes/list.php"]').length > 0 || $(this).closest('div, p').find('a[href*="/user/info.php"]').length > 0)) { const container = $(this).closest('div, p').first(); if (container.length > 0) { container.addClass('gm-highlighted'); } else { $(this).addClass('gm-highlighted'); } } }); } } // 增强留言板功能 function enhanceGuestbook() { $(document).ready(function() { const config = getConfig(); // 添加留言板增强功能 const guestbookEnhancement = `
留言板增强功能:
`; $('body').prepend(guestbookEnhancement); // 绑定事件 $('#gm-guest-hide-replies').click(function() { hideOwnReplies(); }); $('#gm-guest-highlight').click(function() { config.highlightOwn = !config.highlightOwn; saveConfig(config); if (config.highlightOwn) { $(this).addClass('gm-btn-success'); highlightOwnGuestbookMessages(); } else { $(this).removeClass('gm-btn-success'); $('.gm-highlighted').removeClass('gm-highlighted'); } }); $('#gm-guest-filter-users').click(function() { const user = $('#gm-guest-filter-user').val(); if (user) { filterGuestbookByUser(user); } }); $('#gm-guest-refresh').click(function() { location.reload(); }); // 如果启用了相关功能,立即应用 if (config.highlightOwn) { setTimeout(highlightOwnGuestbookMessages, 500); } }); } // 隐藏自己的回复 function hideOwnReplies() { const username = getCurrentUsername(); if (username) { $('body').find('a, span, div, p').each(function() { if ($(this).text().includes(username) && !$(this).parents('.gm-hidden-content').length) { // 找到包含用户留言的容器并隐藏 const container = $(this).closest('div, p').first(); if (container.length > 0) { container.addClass('gm-hidden-content'); } } }); } } // 高亮留言板中的自己的留言 function highlightOwnGuestbookMessages() { const username = getCurrentUsername(); if (username) { $('body').find('a, span, div, p').each(function() { if ($(this).text().includes(username) && !$(this).parents('.gm-hidden-content').length) { const container = $(this).closest('div, p').first(); if (container.length > 0) { container.addClass('gm-highlighted'); } else { $(this).addClass('gm-highlighted'); } } }); } } // 过滤留言板中的指定用户 function filterGuestbookByUser(username) { // 先显示所有内容 $('.gm-hidden-content').removeClass('gm-hidden-content'); let foundUserEntries = false; $('body').find('a').each(function() { const link = $(this); if (link.attr('href') && link.attr('href').includes('/user/info.php')) { if (link.text().includes(username)) { // 找到指定用户名,显示其留言 const container = link.closest('div, p, table').first(); if (container.length > 0) { container.removeClass('gm-hidden-content'); foundUserEntries = true; } } else { // 不是目标用户,隐藏其留言 const container = link.closest('div, p, table').first(); if (container.length > 0) { container.addClass('gm-hidden-content'); } } } }); if (!foundUserEntries) { alert(`未找到用户"${username}"的留言`); } } // 增强用户个人页面 function enhanceUserProfile() { $(document).ready(function() { // 添加用户页面增强功能 const profileEnhancement = `
用户页面增强功能:
`; $('body').prepend(profileEnhancement); // 绑定事件 $('#gm-profile-send-msg').click(function() { const userId = getParameterByName('id'); if (userId) { window.location.href = `/user/mail.php?id=${userId}`; } else { alert('无法获取用户ID'); } }); $('#gm-profile-block-user').click(function() { const userId = getParameterByName('id'); if (userId) { if (confirm('确定要屏蔽此用户吗?')) { const config = getConfig(); if (!config.blockedUsers.includes(userId)) { config.blockedUsers.push(userId); saveConfig(config); alert('用户已屏蔽'); } else { alert('用户已在屏蔽列表中'); } } } else { alert('无法获取用户ID'); } }); }); } // 添加快速搜索功能 function addQuickSearch() { const searchBox = ` `; $('body').append(searchBox); // 添加搜索按钮 const searchBtn = ` 🔍 `; $('body').append(`
${searchBtn}
`); // 绑定事件 $('#gm-search-trigger').click(function() { $('#gm-quick-search').show(); $('#gm-search-input').focus(); }); $('#gm-search-close').click(function() { $('#gm-quick-search').hide(); }); $('#gm-search-submit').click(function() { const query = $('#gm-search-input').val(); const type = $('#gm-search-type').val(); if (query) { performSearch(query, type); } }); // 回车键搜索 $('#gm-search-input').keypress(function(e) { if (e.which === 13) { $('#gm-search-submit').click(); } }); } // 执行搜索 function performSearch(query, type) { const resultsDiv = $('#gm-search-results'); resultsDiv.html('

搜索中...

'); switch(type) { case 'forum': window.location.href = `/forum/search.php?search=${encodeURIComponent(query)}`; break; case 'notes': // 在当前页面搜索日记 resultsDiv.html(`

已在当前日记页面执行搜索,请使用页面上的搜索功能。

`); break; case 'users': window.location.href = `/user/users.php?search=${encodeURIComponent(query)}`; break; case 'guest': // 在当前页面搜索留言板 resultsDiv.html(`

已在当前留言板页面执行搜索,请使用页面上的搜索功能。

`); break; case 'ai': queryAI(query, (response) => { resultsDiv.html(`
${response}
`); }); break; } } // 添加夜间模式 function addNightMode() { const config = getConfig(); if (config.nightMode) { toggleNightMode(true); } } // 切换夜间模式 function toggleNightMode(forceOn = null) { const config = getConfig(); const isOn = forceOn !== null ? forceOn : !config.nightMode; config.nightMode = isOn; saveConfig(config); if (isOn) { $('body').addClass('gm-night-mode'); } else { $('body').removeClass('gm-night-mode'); } } // 添加一键清空浏览历史功能 function addClearHistoryButton() { // 添加到快速操作面板 const clearBtn = ` 🗑️ `; $('.gm-quick-actions').append(clearBtn); $('#gm-clear-history').click(function() { if (confirm('确定要清空浏览历史记录吗?')) { // 清空GM值中的浏览历史相关数据 const keys = GM_listValues(); for (let i = 0; i < keys.length; i++) { if (keys[i].includes('history') || keys[i].includes('visited')) { GM_deleteValue(keys[i]); } } alert('浏览历史已清空'); } }); } // 显示设置面板 function showSettingsPanel() { const config = getConfig(); const settingsPanel = ` `; // 移除现有的设置面板(如果存在) $('#gm-settings-panel').remove(); $('body').append(settingsPanel); // 绑定事件 $('#gm-settings-save').click(function() { const newConfig = getConfig(); newConfig.nightMode = $('#gm-setting-night-mode').is(':checked'); newConfig.autoRefreshChat = $('#gm-setting-auto-refresh').is(':checked'); newConfig.refreshInterval = parseInt($('#gm-setting-refresh-interval').val()) || 30; newConfig.highlightOwn = $('#gm-setting-highlight-own').is(':checked'); newConfig.hideOldMessages = $('#gm-setting-hide-old').is(':checked'); const blockedUsers = $('#gm-setting-blocked-users').val().split(',').map(id => id.trim()).filter(id => id); newConfig.blockedUsers = blockedUsers; saveConfig(newConfig); // 应用新的设置 if (newConfig.nightMode !== config.nightMode) { toggleNightMode(newConfig.nightMode); } if (newConfig.autoRefreshChat !== config.autoRefreshChat) { if (newConfig.autoRefreshChat) { startAutoRefresh(); } else { stopAutoRefresh(); } } alert('设置已保存,部分设置需刷新页面生效'); }); $('#gm-settings-reset').click(function() { if (confirm('确定要重置所有设置吗?')) { GM_deleteValue('config'); initializeConfig(); alert('设置已重置,刷新页面生效'); location.reload(); } }); $('#gm-settings-close').click(function() { $('#gm-settings-panel').remove(); }); } // 应用已保存的设置 function applySavedSettings() { const config = getConfig(); // 应用夜间模式 if (config.nightMode) { $('body').addClass('gm-night-mode'); } // 应用自动刷新 if (config.autoRefreshChat && window.location.href.includes('/chat/')) { startAutoRefresh(); } } // 添加页面特定功能 function addPageSpecificFeatures() { // 在论坛帖子页面添加AI助手按钮 if (window.location.href.match(/\/forum\/\d+\/\d+\/\d+\//)) { const postContent = $('body').find('div, p').filter(function() { return $(this).text().length > 50; // 找到可能的帖子内容 }).first(); if (postContent.length > 0) { const aiAnalyzeBtn = ` `; postContent.before(aiAnalyzeBtn); $('#gm-ai-analyze-post').click(function() { const postText = postContent.text().substring(0, 500); // 限制长度 if (postText.length > 10) { queryAI(`请分析以下帖子内容:${postText}`, (response) => { showAIResponse(`AI分析结果:\n${response}`); }); } }); } } } // 添加AI助手功能 function addAIAssistant() { const config = getConfig(); const aiAssistant = `
AI助手
您好!我是您的AI助手,可以回答关于DCMS论坛的问题,帮助您分析内容,或进行聊天。我可以访问当前页面内容、管理长期记忆、并保持上下文。
`; $('body').append(aiAssistant); // 绑定AI助手事件 $('#gm-ai-send').click(function() { const question = $('#gm-ai-input').val().trim(); if (question) { addAIUserMessage(question); $('#gm-ai-input').val(''); // 获取当前页面内容作为上下文 const pageContent = getCurrentPageContent(); queryAIWithContext(question, pageContent, (response) => { addAIResponseMessage(response); // 更新上下文 const config = getConfig(); config.aiContext.push({ question: question, response: response, timestamp: new Date().toISOString(), pageUrl: window.location.href }); // 限制上下文长度 if (config.aiContext.length > config.aiMemoryLimit) { config.aiContext = config.aiContext.slice(-config.aiMemoryLimit); } saveConfig(config); }); } }); $('#gm-ai-config').click(function() { showAIConfigPanel(); }); $('#gm-ai-close').click(function() { $('#gm-ai-assistant').hide(); }); $('#gm-ai-clear').click(function() { $('#gm-ai-content').html('
对话已清空
'); // 清空上下文 const config = getConfig(); config.aiContext = []; saveConfig(config); }); // 回车键发送 $('#gm-ai-input').keypress(function(e) { if (e.which === 13) { $('#gm-ai-send').click(); } }); // 拖拽功能 dragElement(document.getElementById('gm-ai-assistant'), document.querySelector('#gm-ai-assistant .gm-ai-header')); } // 显示AI配置面板 function showAIConfigPanel() { const config = getConfig(); const configPanel = `

AI助手配置

高级参数设置
添加长期记忆
长期记忆管理
${config.aiLongTermMemory && config.aiLongTermMemory.length > 0 ? config.aiLongTermMemory.map((item, index) => `
${item.title}: ${item.content.substring(0, 100)}...
`).join('') : '
暂无长期记忆
'}
`; // 移除现有的配置面板(如果存在) $('#gm-ai-config-panel').remove(); $('body').append(configPanel); // 绑定事件 $('#gm-ai-config-save').click(function() { const newConfig = getConfig(); newConfig.customApiEnabled = $('#gm-ai-custom-api').is(':checked'); newConfig.apiUrl = $('#gm-ai-api-url').val(); newConfig.apiKey = $('#gm-ai-api-key').val(); newConfig.modelId = $('#gm-ai-model-id').val(); newConfig.maxTokens = parseInt($('#gm-ai-max-tokens').val()) || 512; newConfig.temperature = parseFloat($('#gm-ai-temperature').val()) || 0.7; newConfig.topP = parseFloat($('#gm-ai-top-p').val()) || 0.7; newConfig.topK = parseInt($('#gm-ai-top-k').val()) || 50; newConfig.frequencyPenalty = parseFloat($('#gm-ai-frequency-penalty').val()) || 0.5; newConfig.aiMemoryLimit = parseInt($('#gm-ai-memory-limit').val()) || 10; saveConfig(newConfig); alert('配置已保存'); $('#gm-ai-config-panel').remove(); }); $('#gm-ai-config-cancel').click(function() { $('#gm-ai-config-panel').remove(); }); $('#gm-ai-config-reset').click(function() { if (confirm('确定要重置所有AI记忆吗?')) { const newConfig = getConfig(); newConfig.aiContext = []; newConfig.aiLongTermMemory = []; saveConfig(newConfig); alert('AI记忆已重置'); } }); // 添加记忆 $('#gm-ai-add-memory').click(function() { const title = $('#gm-ai-memory-title').val().trim(); const content = $('#gm-ai-memory-content').val().trim(); if (title && content) { const newConfig = getConfig(); if (!Array.isArray(newConfig.aiLongTermMemory)) { newConfig.aiLongTermMemory = []; } newConfig.aiLongTermMemory.push({ title: title, content: content, timestamp: new Date().toISOString() }); saveConfig(newConfig); // 清空输入框 $('#gm-ai-memory-title').val(''); $('#gm-ai-memory-content').val(''); // 重新显示记忆列表 showAIConfigPanel(); alert('记忆已添加'); } else { alert('请填写标题和内容'); } }); // 删除记忆项目 $(document).on('click', '.gm-ai-delete-memory', function() { const index = parseInt($(this).data('index')); const newConfig = getConfig(); if (Array.isArray(newConfig.aiLongTermMemory) && newConfig.aiLongTermMemory.length > index) { newConfig.aiLongTermMemory.splice(index, 1); saveConfig(newConfig); showAIConfigPanel(); // 重新显示面板 alert('记忆已删除'); } }); } // 强化版页面内容抓取函数 function getCurrentPageContent() { const url = window.location.href; let content = ''; try { // 获取页面基本信息 const title = $('title').text().trim() || document.title || '未知标题'; const pathname = window.location.pathname; content += `页面URL: ${url}\n`; content += `页面标题: ${title}\n`; content += `页面路径: ${pathname}\n\n`; // 根据不同页面类型进行深度内容抓取 if (url.includes('/forum/')) { content += '=== 论坛页面内容 ===\n'; content += getForumPageContent(url); } else if (url.includes('/plugins/notes/')) { content += '=== 日记页面内容 ===\n'; content += getNotesPageContent(url); } else if (url.includes('/chat/')) { content += '=== 聊天室页面内容 ===\n'; content += getChatPageContent(url); } else if (url.includes('/guest/')) { content += '=== 留言板页面内容 ===\n'; content += getGuestbookPageContent(url); } else if (url.includes('/user/info.php')) { content += '=== 用户资料页面内容 ===\n'; content += getUserPageContent(url); } else { content += '=== 首页内容 ===\n'; content += getHomePageContent(url); } // 限制内容长度以避免过长 if (content.length > 2000) { content = content.substring(0, 2000) + '... (内容已截断)'; } } catch (error) { console.error('页面内容抓取错误:', error); content = `页面URL: ${url}\n页面内容抓取失败: ${error.message}`; } return content; } // 获取论坛页面内容 function getForumPageContent(url) { let content = ''; // 获取论坛标题和描述 const forumTitle = $('h1, h2, h3').first().text().trim(); if (forumTitle) { content += `论坛标题: ${forumTitle}\n`; } // 获取帖子列表或帖子内容 if (url.match(/\/\d+\/\d+\/\d+\//)) { // 具体帖子页面 content += '帖子内容:\n'; const postElements = $('body').find('div, p, span').filter(function() { return $(this).text().trim().length > 10 && !$(this).find('script, style').length && !$(this).hasClass('gm-') && // 排除插件生成的内容 !$(this).parents('.gm-').length; }); postElements.each(function(index) { if (index < 10) { // 限制抓取数量 const text = $(this).text().trim(); if (text.length > 20) { content += `- ${text.substring(0, 100)}...\n`; } } }); } else { // 论坛列表页面 content += '帖子列表:\n'; $('a[href*="/forum/"]').each(function(index) { if (index < 15) { // 限制抓取数量 const linkText = $(this).text().trim(); const href = $(this).attr('href'); if (linkText && href && linkText.length > 5) { content += `- ${linkText} (${href})\n`; } } }); } return content; } // 获取日记页面内容 function getNotesPageContent(url) { let content = ''; // 获取日记标题(如果有) const noteTitle = $('h1, h2, h3').first().text().trim(); if (noteTitle) { content += `日记标题: ${noteTitle}\n`; } // 获取日记列表或具体日记内容 if (url.includes('/plugins/notes/list.php')) { // 具体日记页面 content += '日记内容:\n'; const noteContent = $('body').text().substring(0, 500); content += noteContent + '\n'; } else { // 日记列表页面 content += '日记列表:\n'; $('a[href*="/plugins/notes/list.php"]').each(function(index) { if (index < 10) { const linkText = $(this).text().trim(); const userText = $(this).prevAll('a[href*="/user/info.php"]').first().text().trim(); if (linkText && linkText.length > 5) { content += `- ${userText}: ${linkText}\n`; } } }); } return content; } // 获取聊天室页面内容 function getChatPageContent(url) { let content = ''; // 获取聊天室名称 const roomName = $('h1, h2, h3').first().text().trim(); if (roomName) { content += `聊天室: ${roomName}\n`; } // 获取最近聊天记录 content += '最近聊天记录:\n'; const chatMessages = $('body').find('div, p, span').filter(function() { return $(this).text().trim().length > 5 && !$(this).find('script, style').length && !$(this).hasClass('gm-') && !$(this).parents('.gm-').length; }); chatMessages.slice(0, 8).each(function() { const text = $(this).text().trim(); if (text.length > 10 && text.length < 200) { content += `- ${text}\n`; } }); return content; } // 获取留言板页面内容 function getGuestbookPageContent(url) { let content = ''; // 获取留言板标题 const guestbookTitle = $('h1, h2, h3').first().text().trim(); if (guestbookTitle) { content += `留言板: ${guestbookTitle}\n`; } // 获取留言内容 content += '最新留言:\n'; $('body').find('div, p').each(function(index) { if (index < 10) { const text = $(this).text().trim(); if (text.length > 15 && text.length < 150) { // 检查是否包含时间或用户名特征 if (text.includes(':') || text.match(/\d{1,2}:\d{2}/)) { content += `- ${text}\n`; } } } }); return content; } // 获取用户页面内容 function getUserPageContent(url) { let content = ''; // 获取用户名 const username = $('h1, h2, h3').first().text().trim() || $('a[href*="/user/info.php"]').first().text().trim(); if (username) { content += `用户名: ${username}\n`; } // 获取用户ID const userId = getParameterByName('id'); if (userId) { content += `用户ID: ${userId}\n`; } // 获取用户信息 content += '用户信息:\n'; const userInfoElements = $('body').find('div, p, span').filter(function() { return $(this).text().trim().length > 5 && !$(this).find('script, style').length && !$(this).hasClass('gm-') && !$(this).parents('.gm-').length; }); userInfoElements.slice(0, 5).each(function() { const text = $(this).text().trim(); if (text.length > 10 && text.length < 100) { content += `- ${text}\n`; } }); return content; } // 获取首页内容 function getHomePageContent(url) { let content = ''; // 获取新闻和公告 content += '首页内容:\n'; const homeElements = $('body').find('div, p, span').filter(function() { return $(this).text().trim().length > 10 && !$(this).find('script, style').length && !$(this).hasClass('gm-') && !$(this).parents('.gm-').length; }); homeElements.slice(0, 10).each(function() { const text = $(this).text().trim(); if (text.length > 15 && text.length < 150) { content += `- ${text}\n`; } }); return content; } // 带上下文的AI查询 function queryAIWithContext(question, pageContent, callback) { const config = getConfig(); // 构建提示词,包含页面内容、上下文和长期记忆 let systemPrompt = "你是一个智能助手,可以帮助用户处理各种问题。你可以访问以下信息:\n\n"; // 添加页面内容 systemPrompt += `当前页面信息:\n${pageContent}\n\n`; // 添加长期记忆 if (Array.isArray(config.aiLongTermMemory) && config.aiLongTermMemory.length > 0) { systemPrompt += `用户的长期记忆:\n`; config.aiLongTermMemory.forEach((item, index) => { systemPrompt += `${index + 1}. ${item.title}: ${item.content}\n`; }); systemPrompt += `\n`; } // 添加短期上下文 if (Array.isArray(config.aiContext) && config.aiContext.length > 0) { systemPrompt += `最近对话历史:\n`; config.aiContext.slice(-5).forEach((item, index) => { // 只取最近5条对话 systemPrompt += `用户: ${item.question}\n助手: ${item.response}\n`; }); systemPrompt += `\n`; } // 添加工具说明 systemPrompt += `你可以使用以下工具来帮助用户:\n`; systemPrompt += `1. 长期记忆存储工具 - 用于记住对用户重要的信息\n`; systemPrompt += ` 使用方法: 在回答中包含 "[存储记忆: 标题 | 内容]" 来存储重要信息到长期记忆\n`; systemPrompt += `2. 页面内容分析工具 - 用于分析当前页面内容\n`; systemPrompt += ` 使用方法: 在回答中包含 "[分析页面]" 来深入分析当前页面\n\n`; systemPrompt += `请根据用户的问题提供帮助,并在适当时候使用工具。`; // 构建完整提示 const fullPrompt = `${systemPrompt}\n\n用户问题: ${question}`; queryAI(fullPrompt, (response) => { // 检查是否有工具调用 handleToolCalls(response, question, callback); }); } // 处理工具调用 function handleToolCalls(response, originalQuestion, callback) { const config = getConfig(); // 检查是否有存储记忆的指令 const memoryMatch = response.match(/\[存储记忆:\s*([^\|]+)\s*\|\s*([^\]]+)\]/); if (memoryMatch) { const title = memoryMatch[1].trim(); const content = memoryMatch[2].trim(); // 存储到长期记忆 if (!Array.isArray(config.aiLongTermMemory)) { config.aiLongTermMemory = []; } config.aiLongTermMemory.push({ title: title, content: content, timestamp: new Date().toISOString() }); saveConfig(config); // 在AI响应中显示工具调用 const toolCallDisplay = `
✓ 已存储记忆: ${title}
`; addAIResponseMessage(toolCallDisplay); // 移除工具调用标记后返回响应 const cleanResponse = response.replace(/\[存储记忆:[^\]]+\]/g, '').trim(); if (cleanResponse) { callback(cleanResponse); } else { callback('我已经为您存储了这条重要信息到长期记忆中。'); } } else { // 直接返回响应 callback(response); } } // 显示AI响应 function showAIResponse(response) { const aiDiv = $('#gm-ai-assistant'); if (aiDiv.is(':hidden')) { aiDiv.show(); } addAIResponseMessage(response); } // 添加AI用户消息 function addAIUserMessage(message) { const contentDiv = $('#gm-ai-content'); const userMessage = `
您: ${message}
`; contentDiv.append(userMessage); contentDiv.scrollTop(contentDiv[0].scrollHeight); } // 添加AI响应消息 function addAIResponseMessage(message) { const contentDiv = $('#gm-ai-content'); const responseMessage = `
AI: ${message}
`; contentDiv.append(responseMessage); contentDiv.scrollTop(contentDiv[0].scrollHeight); } // AI聊天查询(根据讯飞星火API文档) function queryAI(question, callback) { const config = getConfig(); const apiUrl = config.customApiEnabled ? config.apiUrl : 'https://apis.iflow.cn/v1/chat/completions'; // 准備请求参数(根据讯飞星火API文档) const payload = { model: config.modelId || 'tstars2.0', messages: [ { role: 'user', content: question } ], stream: false, max_tokens: config.maxTokens || 512, temperature: config.temperature || 0.7, top_p: config.topP || 0.7, top_k: config.topK || 50, frequency_penalty: config.frequencyPenalty || 0.5, n: 1, response_format: { type: 'text' } }; // 准備请求头 const headers = { 'Content-Type': 'application/json' }; // 如果提供了API Key,添加认证头 if (config.apiKey) { headers['Authorization'] = `Bearer ${config.apiKey}`; } // 添加错误处理 GM_xmlhttpRequest({ method: 'POST', url: apiUrl, headers: headers, data: JSON.stringify(payload), timeout: 20000, // 20秒超时 onload: function(response) { if (response.status === 200) { let result = response.responseText.trim(); // 尝试解析JSON try { const jsonResult = JSON.parse(result); if (jsonResult && jsonResult.choices && jsonResult.choices.length > 0) { const choice = jsonResult.choices[0]; if (choice.message && choice.message.content) { result = choice.message.content; } else if (typeof jsonResult === 'string') { result = jsonResult; } } else if (jsonResult && jsonResult.content) { result = jsonResult.content; } else if (jsonResult && jsonResult.msg) { result = jsonResult.msg; } else if (jsonResult && jsonResult.response) { result = jsonResult.response; } } catch (e) { // 不是JSON格式,使用原始文本 console.log('响应不是JSON格式:', result); } // 检查返回内容是否有效 if (result && result.length > 0 && !result.toLowerCase().includes('error') && !result.toLowerCase().includes('404')) { callback(result); } else { console.log('API返回错误内容:', result); callback('AI助手暂时无法响应:API返回错误内容'); } } else { console.log('API请求失败,状态码:', response.status); callback('AI助手暂时无法响应:HTTP错误 ' + response.status); } }, onerror: function(error) { console.error('AI API请求错误:', error); callback('AI助手暂时无法响应:网络请求失败'); }, ontimeout: function() { console.log('API请求超时'); callback('AI助手暂时无法响应:请求超时'); } }); } // 切换AI助手显示 function toggleAIAssistant() { const aiDiv = $('#gm-ai-assistant'); if (aiDiv.is(':hidden')) { aiDiv.show(); } else { aiDiv.hide(); } } // 拖拽元素功能 function dragElement(elmnt, header) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; if (header) { header.onmousedown = dragMouseDown; } else { elmnt.onmousedown = dragMouseDown; } function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; elmnt.style.top = (elmnt.offsetTop - pos2) + "px"; elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; } } // 获取URL参数 function getParameterByName(name, url = window.location.href) { name = name.replace(/[\[\]]/g, '\\$&'); const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'); const results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } // 等待jQuery加载完成 waitForJQuery(); })();