您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
提高效率
当前为
// ==UserScript== // @name LLM多站点 // @namespace http://tampermonkey.net/ // @version 1.0.3 // @description 提高效率 // @author wz // @match https://www.kimi.com/* // @match https://chat.deepseek.com/* // @match https://www.tongyi.com/* // @match https://chatgpt.com/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @license GPL-3.0-only // ==/UserScript== (function () { 'use strict'; console.log("ai script, start"); const CACHE_PREFIX = "tool-"; const SPLIT_CHAR = ",,,"; const url = window.location.href; let MAIN_SITE = 0; let activeSites = [1, 2]; let site = 0; let lock = false; const keywords = { "kimi": 0, "deepseek": 1, "tongyi": 2, "chatgpt": 3 }; for (const keyword in keywords) { if (url.indexOf(keyword) > -1) { site = keywords[keyword]; break; } } const historySites = { 0: "https://www.kimi.com/chat/", 1: "https://chat.deepseek.com/a/chat/s/", 2: "https://www.tongyi.com/?sessionId=", 3: "https://chatgpt.com/c/" } const newSites = { 0: "https://www.kimi.com/", 1: "https://chat.deepseek.com/", 2: "https://www.tongyi.com/", 3: "https://chatgpt.com/" } function getChatId(){ let url = getUrl(); let subStr = url.substring(url.lastIndexOf('/') + 1); // console.log("subStr: "+subStr); if(isEmpty(subStr)){ return ""; } if(site === 2){ let mark = 'sessionId='; let tmp = url.lastIndexOf(mark) + mark.length; return url.substring(tmp); }else{ return subStr; } } function getUrl(){ return window.location.href; } function getS(key){ return localStorage.getItem(key); } function setS(key, val){ return localStorage.setItem(key, val); } function setGV(key, value){ GM_setValue(key, value); } function getGV(key){ return GM_getValue(key); } let len = 0; // setInterval(function(){ // masterCheckNew(); // receiveNew(); // }, 2000); // 发送端 let masterId = ""; if(site === MAIN_SITE){ setInterval(masterCheckNew, 2000); } // 接收端 if(activeSites.includes(site)){ setInterval(receiveNew, 2000); }; function masterCheckNew(){ masterId = getChatId(); let bindPrefix = "bind-" + masterId + "-"; // 不同sourceId的bindJson的key不同,挨个读取处理 for(let sourceId of activeSites){ // 如果当前masterId的该slaveId已处理过,则跳过 let bindKey = bindPrefix + sourceId; if(getS(bindKey)){ continue; } let bindIdJson = getGV("slaveId-"+sourceId); if(!isEmpty(bindIdJson)){ let slaveId = bindIdJson.slaveId; let bindMasterId = bindIdJson.masterId; console.log("bindIdJson: "+JSON.stringify(bindIdJson)); // 来者的masterId与当前masterId相同吗?不同则无视 if(masterId === bindMasterId){ // 相同则取出绑定关系的json,空则new一个写入,非空且不存在该slaveId则写入 let oldJson = getS(bindMasterId); if(!isEmpty(oldJson)){ oldJson = JSON.parse(oldJson); console.log("masterId:"+bindMasterId+", oldJson: "+JSON.stringify(oldJson)); let specificSlaveId = oldJson[sourceId]; if(isEmpty(specificSlaveId)){ oldJson[sourceId] = slaveId; setS(bindMasterId, JSON.stringify(oldJson)); } }else{ oldJson = {}; oldJson[sourceId] = slaveId; setS(bindMasterId, JSON.stringify(oldJson)); } // bind关系已完成写入,下次不再读取GV内容 setS(bindKey, true); } } } let questions = []; if(site == 0){ questions = document.getElementsByClassName("user-content"); }else if(site == 1){ // let scrollable = document.getElementsByClassName("scrollable")[1]; // if(!isEmpty(scrollable)){ // questions = new Array(Math.floor(scrollable.firstElementChild.firstElementChild.children.length / 2)); // }else{ // questions = []; // } }else if(site == 2){ questions = document.querySelectorAll('[class^="bubble-"]'); } let lenNext = questions.length; if(lenNext > 0){ len = getS(CACHE_PREFIX + masterId); if(lenNext > len){ let lastQ = questions[lenNext - 1]; masterReq(masterId, lastQ); setS(CACHE_PREFIX + masterId, lenNext); } } }; function masterReq(masterId, lastQ){ let slaveIdJson = getS(masterId); var message = { masterId: masterId, question: lastQ.textContent, slaveId: slaveIdJson, site: site }; console.log(message); setGV("question", message); } function receiveNew(){ let curSlaveId = getChatId(); if(curSlaveId.length < 12){ curSlaveId = ""; } let questionBeforeJump = getS("questionBeforeJump"); // 如果是经跳转而来,无需处理主节点信息,直接从缓存取对话内容 if(!isEmpty(questionBeforeJump)){ console.log("questionBeforeJump: " + questionBeforeJump); let splits = questionBeforeJump.split(SPLIT_CHAR); let cachedQuestion = splits[0]; let cachedMasterId = splits[1]; let lastQuestion = getS("lastQuestion"); if(!isEmpty(cachedQuestion) && cachedQuestion !== lastQuestion){ // 清空跳转用的缓存 setS("questionBeforeJump", ""); abstractSend(site, cachedQuestion); if(isEmpty(curSlaveId)){ bindIdPair(cachedMasterId); } // 给lastQuestion缓存设值 setS("lastQuestion", cachedQuestion); } return; } // 读取主节点信息并处理 let msg = getGV("question"); if(!isEmpty(msg)){ let masterId = msg.masterId; let question = msg.question; // 如果问题已经问过,不再处理 let lastQuestion = getS("lastQuestion"); let sameQuestion = !isEmpty(lastQuestion) && question === lastQuestion; if(sameQuestion){ return; } console.log("slave msg: " + msg); let slaveIdFlag = false; let mSlaveId = ""; let slaveIdJson = msg.slaveId; // 是否传递了当前网站的slaveId if(!isEmpty(slaveIdJson)){ mSlaveId = JSON.parse(slaveIdJson)[site]; if(!isEmpty(mSlaveId)){ slaveIdFlag = true; } } let curIdFlag = !isEmpty(curSlaveId); let targetUrl = ""; // 下面的逻辑分支看着复杂,但根本是关于 slaveIdFlag 和 curIdFlag 的不同布尔值的分支 if(slaveIdFlag){ if(curIdFlag){ if(curSlaveId === mSlaveId){ if(!sameQuestion){ setS("lastQuestion", question); abstractSend(site, question); } }else{ targetUrl = historySites[site] + mSlaveId; } }else{ targetUrl = historySites[site] + mSlaveId; } }else{ if(curIdFlag){ targetUrl = newSites[site]; }else{ setS("lastQuestion", question); abstractSend(site, question); bindIdPair(masterId); } } if(!isEmpty(targetUrl)){ setS("questionBeforeJump", question + SPLIT_CHAR + masterId); window.location.href = targetUrl; } } }; function bindIdPair(masterId){ let intervalId; let lastUrl = getUrl(); let count = 0; let gap = 100; intervalId = setInterval(function() { count ++; if(count > 5000 / gap){ clearInterval(intervalId); } let currentUrl = getUrl(); if (currentUrl !== lastUrl) { let bindIdJson = { slaveId: getChatId(), masterId: masterId }; console.log("set json: "+ JSON.stringify(bindIdJson)); setGV('slaveId-'+site, bindIdJson); clearInterval(intervalId); } }, gap); } function abstractSend(site, content){ let intervalId; let count = 0; let gap = 100; intervalId = setInterval(function() { count ++; if(count > 5000 / gap){ clearInterval(intervalId); } let textarea = getTextArea(site); if (!isEmpty(textarea)) { textarea.focus(); document.execCommand('insertText', false, content); setTimeout(function(){ let sendBtn = getBtn(site); sendBtn.click(); }, 100); clearInterval(intervalId); } }, gap); } function getTextArea(site){ if(site == 0){ return document.getElementsByClassName('chat-input-editor')[0]; }else if(site === 1){ return document.getElementById('chat-input'); }else if(site === 2){ return document.getElementsByTagName('textarea')[0]; }else if(site === 3){ return document.getElementById('prompt-textarea'); } } function getBtn(site){ if(site == 0){ return document.getElementsByClassName('send-button-container')[0]; }else if(site === 1){ var btns = document.querySelectorAll('[role="button"]'); return btns[btns.length - 1]; }else if(site === 2){ return document.querySelectorAll('[class^="operateBtn-"], [class*=" operateBtn-"]')[0]; }else if(site === 3){ return document.getElementById('composer-submit-button'); } } function isEmpty(item){ if(item===null || item===undefined || item.length===0 || item === "null"){ return true; }else{ return false; } } })();