您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为SexyAI/魅魔岛网站的每个作品提供独立的外部留言板功能,支持匿名留言、表情、图片等
// ==UserScript== // @name 【SexyAI / 魅魔岛】作品留言板本地存储(无法互动) // @name:zh 【SexyAI】作品留言板 // @name:zh-CN 【SexyAI】作品留言板 // @name:en 【SexyAI】Work Comment Board // @namespace https://gf.qytechs.cn/users/SexyAI-CommentBoard // @version 1.0.0 // @description 为SexyAI/魅魔岛网站的每个作品提供独立的外部留言板功能,支持匿名留言、表情、图片等 // @description:zh 为SexyAI/魅魔岛网站的每个作品提供独立的外部留言板功能 // @description:zh-CN 为SexyAI/魅魔岛网站的每个作品提供独立的外部留言板功能 // @description:en Add external comment board for each work on SexyAI website // @author SexyAI-CommentBoard // @match https://www.sexyai.top/* // @match https://sexyai.top/* // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @require https://code.jquery.com/jquery-3.6.0.min.js // @license CC BY-NC 4.0 // ==/UserScript== /* 【SexyAI / 魅魔岛】作品留言板 © 2024 by SexyAI-CommentBoard is licensed under CC BY-NC 4.0. To view a copy of this license, visit https://creativecommons.org/licenses/by-nc/4.0/ */ (function() { 'use strict'; // 配置选项 let isCommentBoardEnabled = GM_getValue('isCommentBoardEnabled', true); let boardPosition = GM_getValue('boardPosition', 'right-side'); let boardTheme = GM_getValue('boardTheme', 'dark'); let showBoardByDefault = GM_getValue('showBoardByDefault', false); let allowAnonymous = GM_getValue('allowAnonymous', true); let maxCommentsPerWork = GM_getValue('maxCommentsPerWork', 100); // 全局变量 let currentWorkId = null; let commentBoard = null; let isMinimized = !showBoardByDefault; let pageObserver = null; // 表情包数据 const emojis = [ '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣', '😊', '😇', '🙂', '🙃', '😉', '😌', '😍', '🥰', '😘', '😗', '😙', '😚', '😋', '😛', '😝', '😜', '🤪', '🤨', '🧐', '🤓', '😎', '🤩', '🥳', '😏', '😒', '😞', '😔', '😟', '😕', '🙁', '☹️', '😣', '😖', '😫', '😩', '🥺', '😢', '😭', '😤', '😠', '😡', '🤬', '🤯', '😳', '🥵', '🥶', '😱', '😨', '😰', '😥', '😓', '🤗', '🤔', '🤭', '🤫', '🤥', '😶', '😐', '😑', '😬', '🙄', '😯', '😦', '😧', '😮', '😲', '🥱', '😴', '🤤', '😪', '😵', '🤐', '🥴', '🤢', '🤮', '🤧', '😷', '🤒', '🤕', '🤑', '🤠', '😈', '👿', '👹', '👺', '🤡', '💩', '👻', '💀', '☠️', '👽', '👾', '🤖', '🎃', '😺', '😸', '😹', '😻', '😼', '😽', '🙀', '😿', '😾', '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💔', '❣️', '💕', '💞', '💓', '💗', '💖', '💘', '💝', '💟', '👍', '👎', '👌', '🤏', '✌️', '🤞', '🤟', '🤘', '🤙', '👈', '👉', '👆', '🖕', '👇', '☝️', '👋', '🤚', '🖐️', '✋', '🖖', '👏', '🙌', '🤲', '🤝', '🙏', '✍️', '💪', '🦾', '🦿', '🦵' ]; // 添加样式 const style = document.createElement('style'); style.textContent = ` /* SexyAI 作品留言板样式 */ #sexyai-comment-board { position: fixed; z-index: 9999; width: 350px; max-height: 80vh; background: linear-gradient(135deg, rgba(20, 20, 30, 0.98), rgba(30, 20, 40, 0.98)); border: 2px solid #ff6b9d; border-radius: 15px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.7); backdrop-filter: blur(10px); font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: white; overflow: hidden; transition: all 0.3s ease; } #sexyai-comment-board.minimized { height: 50px !important; max-height: 50px !important; } #sexyai-comment-board.right-side { top: 50%; right: 20px; transform: translateY(-50%); } #sexyai-comment-board.left-side { top: 50%; left: 20px; transform: translateY(-50%); } #sexyai-comment-board.bottom-right { bottom: 20px; right: 20px; } #sexyai-comment-board.bottom-left { bottom: 20px; left: 20px; } .comment-board-header { background: linear-gradient(45deg, #ff6b9d, #4ecdc4); padding: 12px 15px; display: flex; justify-content: space-between; align-items: center; cursor: pointer; user-select: none; } .comment-board-title { font-weight: bold; font-size: 14px; display: flex; align-items: center; gap: 8px; } .comment-count { background: rgba(255, 255, 255, 0.2); padding: 2px 8px; border-radius: 10px; font-size: 11px; } .comment-board-controls { display: flex; gap: 8px; align-items: center; } .control-btn { background: rgba(255, 255, 255, 0.2); border: none; color: white; width: 24px; height: 24px; border-radius: 50%; cursor: pointer; font-size: 12px; transition: all 0.2s ease; } .control-btn:hover { background: rgba(255, 255, 255, 0.3); transform: scale(1.1); } .comment-board-content { display: flex; flex-direction: column; height: calc(80vh - 50px); max-height: 600px; } .comment-board.minimized .comment-board-content { display: none; } .comments-list { flex: 1; overflow-y: auto; padding: 15px; max-height: 400px; } .comment-item { background: rgba(255, 255, 255, 0.05); border-radius: 10px; padding: 12px; margin-bottom: 10px; border-left: 3px solid #ff6b9d; transition: all 0.2s ease; } .comment-item:hover { background: rgba(255, 255, 255, 0.08); transform: translateX(2px); } .comment-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 12px; } .comment-author { font-weight: bold; color: #4ecdc4; } .comment-time { color: #ccc; font-size: 11px; } .comment-content { font-size: 13px; line-height: 1.4; word-wrap: break-word; } .comment-actions { margin-top: 8px; display: flex; gap: 8px; } .comment-action-btn { background: none; border: none; color: #ccc; font-size: 11px; cursor: pointer; padding: 2px 6px; border-radius: 4px; transition: all 0.2s ease; } .comment-action-btn:hover { background: rgba(255, 107, 157, 0.2); color: #ff6b9d; } .comment-input-area { border-top: 1px solid rgba(255, 107, 157, 0.3); padding: 15px; background: rgba(0, 0, 0, 0.2); } .comment-input { width: 100%; min-height: 60px; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 107, 157, 0.5); border-radius: 8px; padding: 10px; color: white; font-size: 13px; resize: vertical; font-family: inherit; } .comment-input:focus { outline: none; border-color: #ff6b9d; box-shadow: 0 0 10px rgba(255, 107, 157, 0.3); } .comment-input::placeholder { color: #ccc; } .input-controls { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; } .emoji-picker { display: flex; gap: 4px; flex-wrap: wrap; max-width: 200px; } .emoji-btn { background: none; border: none; font-size: 16px; cursor: pointer; padding: 2px; border-radius: 4px; transition: all 0.2s ease; } .emoji-btn:hover { background: rgba(255, 107, 157, 0.2); transform: scale(1.2); } .submit-btn { background: linear-gradient(45deg, #4ecdc4, #45b7aa); color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer; font-weight: bold; font-size: 12px; transition: all 0.3s ease; } .submit-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(78, 205, 196, 0.4); } .submit-btn:disabled { opacity: 0.5; cursor: not-allowed; } .author-input { background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 107, 157, 0.3); border-radius: 6px; padding: 6px 10px; color: white; font-size: 12px; width: 100px; margin-bottom: 8px; } .author-input:focus { outline: none; border-color: #ff6b9d; } .no-comments { text-align: center; color: #ccc; font-style: italic; padding: 30px 15px; } .work-info { background: rgba(78, 205, 196, 0.1); padding: 10px; margin-bottom: 10px; border-radius: 8px; font-size: 12px; border-left: 3px solid #4ecdc4; } .settings-panel { position: absolute; top: 100%; right: 0; background: rgba(20, 20, 30, 0.98); border: 1px solid #ff6b9d; border-radius: 8px; padding: 15px; min-width: 200px; box-shadow: 0 5px 20px rgba(0, 0, 0, 0.5); display: none; z-index: 10000; } .settings-item { margin-bottom: 10px; } .settings-label { display: block; font-size: 12px; margin-bottom: 5px; color: #ccc; } .settings-select { width: 100%; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 107, 157, 0.3); border-radius: 4px; padding: 4px 8px; color: white; font-size: 12px; } .settings-checkbox { margin-right: 6px; } /* 滚动条样式 */ .comments-list::-webkit-scrollbar { width: 6px; } .comments-list::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.1); border-radius: 3px; } .comments-list::-webkit-scrollbar-thumb { background: rgba(255, 107, 157, 0.5); border-radius: 3px; } .comments-list::-webkit-scrollbar-thumb:hover { background: rgba(255, 107, 157, 0.7); } /* 动画效果 */ @keyframes slideIn { from { opacity: 0; transform: translateX(100%); } to { opacity: 1; transform: translateX(0); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .comment-item { animation: fadeIn 0.3s ease; } #sexyai-comment-board { animation: slideIn 0.3s ease; } `; document.head.appendChild(style); // 获取当前作品ID function getCurrentWorkId() { const url = window.location.href; // 尝试从URL中提取作品ID const patterns = [ /\/work\/([^/?]+)/, /\/chat\/([^/?]+)/, /\/character\/([^/?]+)/, /\/story\/([^/?]+)/, /\/image\/([^/?]+)/, /id=([^&]+)/, /workId=([^&]+)/, /characterId=([^&]+)/ ]; for (const pattern of patterns) { const match = url.match(pattern); if (match) { return match[1]; } } // 如果URL中没有明确的ID,尝试从页面元素中获取 const titleElement = document.querySelector('h1, .title, .work-title, .character-name'); if (titleElement) { const title = titleElement.textContent.trim(); if (title) { // 使用标题的哈希值作为ID return btoa(encodeURIComponent(title)).replace(/[^a-zA-Z0-9]/g, '').substring(0, 16); } } // 最后使用URL路径作为ID return btoa(encodeURIComponent(window.location.pathname)).replace(/[^a-zA-Z0-9]/g, '').substring(0, 16); } // 获取作品信息 function getWorkInfo() { const titleElement = document.querySelector('h1, .title, .work-title, .character-name, .chat-title'); const title = titleElement ? titleElement.textContent.trim() : '未知作品'; const authorElement = document.querySelector('.author, .creator, .username, .character-author'); const author = authorElement ? authorElement.textContent.trim() : '未知作者'; return { title, author }; } // 创建留言板 function createCommentBoard() { const board = document.createElement('div'); board.id = 'sexyai-comment-board'; board.className = boardPosition + (isMinimized ? ' minimized' : ''); const workInfo = getWorkInfo(); const comments = getComments(currentWorkId); board.innerHTML = ` <div class="comment-board-header"> <div class="comment-board-title"> 💬 留言板 <span class="comment-count">${comments.length}</span> </div> <div class="comment-board-controls"> <button class="control-btn" id="settings-btn" title="设置">⚙️</button> <button class="control-btn" id="minimize-btn" title="${isMinimized ? '展开' : '收起'}">${isMinimized ? '📖' : '📕'}</button> <button class="control-btn" id="close-btn" title="关闭">✖️</button> </div> <div class="settings-panel" id="settings-panel"> <div class="settings-item"> <label class="settings-label">位置</label> <select class="settings-select" id="position-select"> <option value="right-side">右侧</option> <option value="left-side">左侧</option> <option value="bottom-right">右下角</option> <option value="bottom-left">左下角</option> </select> </div> <div class="settings-item"> <label class="settings-label"> <input type="checkbox" class="settings-checkbox" id="show-by-default"> 默认展开 </label> </div> <div class="settings-item"> <label class="settings-label"> <input type="checkbox" class="settings-checkbox" id="allow-anonymous"> 允许匿名 </label> </div> </div> </div> <div class="comment-board-content"> <div class="work-info"> <strong>📖 ${workInfo.title}</strong><br> <small>👤 ${workInfo.author}</small> </div> <div class="comments-list" id="comments-list"> ${renderComments(comments)} </div> <div class="comment-input-area"> ${allowAnonymous ? '' : '<input type="text" class="author-input" id="author-input" placeholder="您的昵称" maxlength="20">'} <textarea class="comment-input" id="comment-input" placeholder="写下您的留言..." maxlength="500"></textarea> <div class="input-controls"> <div class="emoji-picker"> ${emojis.slice(0, 10).map(emoji => `<button class="emoji-btn" data-emoji="${emoji}">${emoji}</button>`).join('')} </div> <button class="submit-btn" id="submit-comment">发送</button> </div> </div> </div> `; return board; } // 渲染评论列表 function renderComments(comments) { if (comments.length === 0) { return '<div class="no-comments">暂无留言,快来抢沙发吧!</div>'; } return comments.map(comment => ` <div class="comment-item" data-id="${comment.id}"> <div class="comment-header"> <span class="comment-author">${comment.author}</span> <span class="comment-time">${formatTime(comment.timestamp)}</span> </div> <div class="comment-content">${escapeHtml(comment.content)}</div> <div class="comment-actions"> <button class="comment-action-btn like-btn" data-id="${comment.id}"> 👍 ${comment.likes || 0} </button> <button class="comment-action-btn reply-btn" data-id="${comment.id}"> 💬 回复 </button> <button class="comment-action-btn delete-btn" data-id="${comment.id}"> 🗑️ 删除 </button> </div> </div> `).join(''); } // 获取评论数据 function getComments(workId) { const key = `comments_${workId}`; const comments = GM_getValue(key, '[]'); try { return JSON.parse(comments); } catch (e) { console.error('解析评论数据失败:', e); return []; } } // 保存评论数据 function saveComments(workId, comments) { const key = `comments_${workId}`; // 限制评论数量 if (comments.length > maxCommentsPerWork) { comments = comments.slice(-maxCommentsPerWork); } GM_setValue(key, JSON.stringify(comments)); } // 添加评论 function addComment(workId, content, author) { const comments = getComments(workId); const newComment = { id: Date.now().toString(), content: content.trim(), author: author || (allowAnonymous ? '匿名用户' : '游客'), timestamp: Date.now(), likes: 0 }; comments.push(newComment); saveComments(workId, comments); return newComment; } // 删除评论 function deleteComment(workId, commentId) { const comments = getComments(workId); const filteredComments = comments.filter(c => c.id !== commentId); saveComments(workId, filteredComments); } // 点赞评论 function likeComment(workId, commentId) { const comments = getComments(workId); const comment = comments.find(c => c.id === commentId); if (comment) { comment.likes = (comment.likes || 0) + 1; saveComments(workId, comments); } } // 格式化时间 function formatTime(timestamp) { const now = Date.now(); const diff = now - timestamp; if (diff < 60000) { return '刚刚'; } else if (diff < 3600000) { return Math.floor(diff / 60000) + '分钟前'; } else if (diff < 86400000) { return Math.floor(diff / 3600000) + '小时前'; } else { const date = new Date(timestamp); return `${date.getMonth() + 1}/${date.getDate()}`; } } // HTML转义 function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // 初始化留言板事件 function initCommentBoardEvents() { if (!commentBoard) return; // 头部点击切换最小化 const header = commentBoard.querySelector('.comment-board-header'); header.addEventListener('click', (e) => { if (e.target.closest('.comment-board-controls')) return; toggleMinimize(); }); // 最小化按钮 const minimizeBtn = commentBoard.querySelector('#minimize-btn'); minimizeBtn.addEventListener('click', (e) => { e.stopPropagation(); toggleMinimize(); }); // 关闭按钮 const closeBtn = commentBoard.querySelector('#close-btn'); closeBtn.addEventListener('click', (e) => { e.stopPropagation(); hideCommentBoard(); }); // 设置按钮 const settingsBtn = commentBoard.querySelector('#settings-btn'); const settingsPanel = commentBoard.querySelector('#settings-panel'); settingsBtn.addEventListener('click', (e) => { e.stopPropagation(); settingsPanel.style.display = settingsPanel.style.display === 'block' ? 'none' : 'block'; }); // 设置选项 const positionSelect = commentBoard.querySelector('#position-select'); positionSelect.value = boardPosition; positionSelect.addEventListener('change', (e) => { boardPosition = e.target.value; GM_setValue('boardPosition', boardPosition); updateBoardPosition(); }); const showByDefaultCheckbox = commentBoard.querySelector('#show-by-default'); showByDefaultCheckbox.checked = showBoardByDefault; showByDefaultCheckbox.addEventListener('change', (e) => { showBoardByDefault = e.target.checked; GM_setValue('showBoardByDefault', showBoardByDefault); }); const allowAnonymousCheckbox = commentBoard.querySelector('#allow-anonymous'); allowAnonymousCheckbox.checked = allowAnonymous; allowAnonymousCheckbox.addEventListener('change', (e) => { allowAnonymous = e.target.checked; GM_setValue('allowAnonymous', allowAnonymous); refreshCommentBoard(); }); // 表情按钮 const emojiButtons = commentBoard.querySelectorAll('.emoji-btn'); const commentInput = commentBoard.querySelector('#comment-input'); emojiButtons.forEach(btn => { btn.addEventListener('click', () => { const emoji = btn.dataset.emoji; const cursorPos = commentInput.selectionStart; const textBefore = commentInput.value.substring(0, cursorPos); const textAfter = commentInput.value.substring(commentInput.selectionEnd); commentInput.value = textBefore + emoji + textAfter; commentInput.focus(); commentInput.setSelectionRange(cursorPos + emoji.length, cursorPos + emoji.length); }); }); // 发送评论 const submitBtn = commentBoard.querySelector('#submit-comment'); submitBtn.addEventListener('click', submitComment); // 回车发送 commentInput.addEventListener('keydown', (e) => { if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { e.preventDefault(); submitComment(); } }); // 评论操作 const commentsList = commentBoard.querySelector('#comments-list'); commentsList.addEventListener('click', (e) => { const target = e.target; const commentId = target.dataset.id; if (target.classList.contains('like-btn')) { likeComment(currentWorkId, commentId); refreshCommentsList(); } else if (target.classList.contains('delete-btn')) { if (confirm('确定要删除这条评论吗?')) { deleteComment(currentWorkId, commentId); refreshCommentsList(); } } else if (target.classList.contains('reply-btn')) { const commentItem = target.closest('.comment-item'); const author = commentItem.querySelector('.comment-author').textContent; commentInput.value = `@${author} `; commentInput.focus(); } }); // 点击外部关闭设置面板 document.addEventListener('click', (e) => { if (!e.target.closest('#settings-panel') && !e.target.closest('#settings-btn')) { settingsPanel.style.display = 'none'; } }); } // 提交评论 function submitComment() { const commentInput = commentBoard.querySelector('#comment-input'); const authorInput = commentBoard.querySelector('#author-input'); const content = commentInput.value.trim(); if (!content) { alert('请输入留言内容'); return; } const author = authorInput ? authorInput.value.trim() : ''; addComment(currentWorkId, content, author); commentInput.value = ''; if (authorInput) authorInput.value = ''; refreshCommentsList(); updateCommentCount(); // 滚动到底部 const commentsList = commentBoard.querySelector('#comments-list'); setTimeout(() => { commentsList.scrollTop = commentsList.scrollHeight; }, 100); } // 刷新评论列表 function refreshCommentsList() { const commentsList = commentBoard.querySelector('#comments-list'); const comments = getComments(currentWorkId); commentsList.innerHTML = renderComments(comments); } // 更新评论数量 function updateCommentCount() { const commentCount = commentBoard.querySelector('.comment-count'); const comments = getComments(currentWorkId); commentCount.textContent = comments.length; } // 切换最小化状态 function toggleMinimize() { isMinimized = !isMinimized; const minimizeBtn = commentBoard.querySelector('#minimize-btn'); if (isMinimized) { commentBoard.classList.add('minimized'); minimizeBtn.textContent = '📖'; minimizeBtn.title = '展开'; } else { commentBoard.classList.remove('minimized'); minimizeBtn.textContent = '📕'; minimizeBtn.title = '收起'; } } // 更新留言板位置 function updateBoardPosition() { commentBoard.className = boardPosition + (isMinimized ? ' minimized' : ''); } // 显示留言板 function showCommentBoard() { if (!isCommentBoardEnabled) return; currentWorkId = getCurrentWorkId(); if (!currentWorkId) return; // 移除旧的留言板 const existingBoard = document.getElementById('sexyai-comment-board'); if (existingBoard) { existingBoard.remove(); } // 创建新的留言板 commentBoard = createCommentBoard(); document.body.appendChild(commentBoard); // 初始化事件 initCommentBoardEvents(); console.log('SexyAI留言板已加载,作品ID:', currentWorkId); } // 隐藏留言板 function hideCommentBoard() { if (commentBoard) { commentBoard.remove(); commentBoard = null; } } // 刷新留言板 function refreshCommentBoard() { if (commentBoard) { hideCommentBoard(); showCommentBoard(); } } // 检测页面变化 function observePageChanges() { let currentUrl = window.location.href; const observer = new MutationObserver(() => { if (window.location.href !== currentUrl) { currentUrl = window.location.href; setTimeout(() => { if (shouldShowCommentBoard()) { showCommentBoard(); } else { hideCommentBoard(); } }, 1000); } }); observer.observe(document.body, { childList: true, subtree: true }); return observer; } // 判断是否应该显示留言板 function shouldShowCommentBoard() { const url = window.location.href; // 检查是否在作品页面 const workPagePatterns = [ /\/work\//, /\/chat\//, /\/character\//, /\/story\//, /\/image\//, /\/pages\/chat/, /\/pages\/character/, /\/pages\/work/ ]; return workPagePatterns.some(pattern => pattern.test(url)); } // 创建控制按钮 function createControlButton() { const button = document.createElement('div'); button.id = 'sexyai-comment-control'; button.innerHTML = '💬'; button.style.cssText = ` position: fixed; top: 50%; right: 10px; transform: translateY(-50%); z-index: 9998; width: 40px; height: 40px; background: linear-gradient(45deg, #ff6b9d, #4ecdc4); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 18px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); transition: all 0.3s ease; `; button.addEventListener('click', () => { if (commentBoard) { hideCommentBoard(); } else { showCommentBoard(); } }); button.addEventListener('mouseenter', () => { button.style.transform = 'translateY(-50%) scale(1.1)'; }); button.addEventListener('mouseleave', () => { button.style.transform = 'translateY(-50%) scale(1)'; }); return button; } // 初始化 function init() { try { console.log('🔥 SexyAI作品留言板插件已启动 v1.0.0'); // 加载设置 isCommentBoardEnabled = GM_getValue('isCommentBoardEnabled', true); boardPosition = GM_getValue('boardPosition', 'right-side'); boardTheme = GM_getValue('boardTheme', 'dark'); showBoardByDefault = GM_getValue('showBoardByDefault', false); allowAnonymous = GM_getValue('allowAnonymous', true); maxCommentsPerWork = GM_getValue('maxCommentsPerWork', 100); // 创建控制按钮 const controlButton = createControlButton(); document.body.appendChild(controlButton); // 开始监听页面变化 pageObserver = observePageChanges(); // 初始检查 setTimeout(() => { if (shouldShowCommentBoard() && showBoardByDefault) { showCommentBoard(); } }, 2000); // 页面卸载时清理 window.addEventListener('beforeunload', () => { if (pageObserver) { pageObserver.disconnect(); } }); } catch (error) { console.error('SexyAI留言板插件初始化失败:', error); } } // 等待页面加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { setTimeout(init, 1000); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址