// ==UserScript==
// @name chatGPT tools Plus(修改版)
// @namespace http://tampermonkey.net/
// @version 1.0.8
// @description chatGPT free version(修改版),Google、必应、百度侧边栏Chat搜索,即刻体验AI,无需翻墙,无需注册,无需等待!
// @author 夜雨
// @match https://cn.bing.com/*
// @match https://www.bing.com/*
// @match https://chat.openai.com/chat
// @match https://www.google.com/*
// @match http*://www.baidu.com/s*
// @match https://www.baidu.com*
// @match https://www.google.com.hk/*
// @include /^https:\/\/www\.baidu\.com\/s\?wd.*$/
// @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @run-at document-end
// @require https://cdn.staticfile.org/jquery/3.4.0/jquery.min.js
// @require https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js
// @require https://cdn.jsdelivr.net/npm/[email protected]/marked.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.1/markdown-it.min.js
// @require https://unpkg.com/axios/dist/axios.min.js
// @connect ip-api.com
// @connect chat.openai.com
// @connect gpt.chatapi.art
// @connect api.forchange.cn
// @connect wenxin110.top
// @connect chatforai.com
// @license MIT
// @resource css https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.css
// @resource css https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/showdown.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js
// ==/UserScript==
(function() {
'use strict';
// @require https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js
//重要声明:感谢隔壁作者:zhengbangbo (https://github.com/zhengbangbo/chat-gpt-userscript)的请求处理方式,之前一直不知道怎么处理SSE响应,原来直接就可以用一般的方式来接收,那么对返回数据处理切割就直接借鉴啦!(反正MIT不是嘛)
//cookie 大家自己想办法弄到,别霍霍我了呜呜
//对返回结果增加了markdown解析成html
//请在上面添加一句:油猴因为策略问题没法增加这个js
//多亏了zhengbangbo大佬,现在已经解决这个策略问题了!
// @require https://cdn.jsdelivr.net/npm/marked/marked.min.js
//enc-start
async function digestMessage(r) {
const hash = CryptoJS.SHA256(r);
return hash.toString(CryptoJS.enc.Hex);
}
const generateSignature = async r => {
const {
t: e,
m: t
} = r;
const n = {}.PUBLIC_SECRET_KEY;
const a = `${e}:${t}:${n}`;
return await digestMessage(a);
};
//enc-end
//start
function addChatBtn() {
let mybtn =
`<span class="bg s_btn_wr"><input type="button" id="mybtn" value="加载chat" class="bg s_btn"></span>`;
$(".bg.s_btn_wr").append(mybtn)
document.getElementById("mybtn").addEventListener("click", function() {
console.log("reloadPage")
if (window.location.href.indexOf("https:\/\/www.baidu.com\/s") > -1) {
GM_add_box_style(2)
addBothStyle()
keyEvent()
appendBox(2).then((res) => {
pivElemAddEventAndValue(2)
})
}
})
}
//end
//顶级配置
//可以手动配置your_cookie!
const requestUrl = `https://gpt.chatapi.art/backend-api/conversation`
var your_qus
var abortXml
if (window.location.href.indexOf("bing.com") > -1) {
getYourCookie()
GM_add_box_style(0)
addBothStyle()
keyEvent()
appendBox(0).then((res) => {
pivElemAddEventAndValue(0)
})
linkToBing_beautification_script()
}
if (window.location.href.indexOf("www.google.com") > -1) {
GM_add_box_style(1)
addBothStyle()
keyEvent()
appendBox(1).then((res) => {
pivElemAddEventAndValue(1)
})
}
if (window.location.href.indexOf("https:\/\/www.baidu.com\/s") > -1) {
GM_add_box_style(2)
addBothStyle()
keyEvent()
appendBox(2).then((res) => {
pivElemAddEventAndValue(2)
})
} else if (window.location.href.indexOf("https:\/\/www.baidu.com") > -1) {
addChatBtn()
}
if (window.location.href.indexOf("chat.openai.com") > -1) {
//$.cookie('yourCookie','dumplings', {domain:'qq.com',path:'/'});
console.log("httpOnly保护,没法拿到cookie,自己复制粘贴控制台")
}
//顶级函数
function uuid() { //uuid 产生
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
function GM_add_box_style(case_web) {
switch (case_web) {
case 0: //bing
GM_addStyle(`
#gptAnswer{
margin: 15px;
border-top: solid;
border-bottom: solid;
}
#gptInput{
width:74%;
border-radius: 4px;
}
#gptInputBox{
display: flex;
justify-content: space-around;
}
#button_GPT:hover{
background:#ffffffcc;
}
#gptDiv{
border-radius: 8px;
padding: 10px;
margin-bottom: 9px;
width:452px;
translate:-20px;
background:#ffffffcc;
backdrop-filter: blur(5px);
display: flex;
flex-direction: column;
}
#button_GPT{
}
#button_GPT{
background: transparent;
border-radius: 4px;
}
#gptCueBox{
translate: 3px;
}
p{white-space: pre-line}
`)
break;
case 1: //google
GM_addStyle(`
#gptAnswer{
margin: 15px;
border-top: solid;
border-bottom: solid;
}
#gptInput{
border-radius: 4px;
width: 68%;
}
#button_GPT:hover{
background:#dcdcdccc;
}
#gptDiv{
width:452px;
flex: 1;
display: flex;
flex-direction: column;
height: fit-content;
}
#gptInputBox{
display:flex;
justify-content: space-around;
}
#button_GPT{
background: transparent;
border-radius: 3px;
font-size: 14px;
}
#gptStatus{
margin-left: 7px;
}
p{white-space: pre-line}
`)
break; //baidu
case 2:
GM_addStyle(`
#gptAnswer{
margin: 15px;
border-top: solid;
border-bottom: solid;
}
#gptInput{
border-radius: 4px;
width: 68%;
}
#button_GPT:hover{
background:#dcdcdccc;
}
#gptDiv{
width:452px;
flex: 1;
display: flex;
flex-direction: column;
height: fit-content;
}
#gptInputBox{
display:flex;
justify-content: space-around;
}
#button_GPT{
background: transparent;
border-radius: 3px;
font-size: 14px;
}
#gptStatus{
margin-left: 7px;
}
p{white-space: pre-line}
`)
break;
default:
alert("参数没设定")
}
}
function do_it() {
let finalResult
let normalArray
let nowResult
document.getElementById('gptAnswer').innerHTML = `<div>加载中<span id="dot"></span></div>`;
const now = Date.now();
console.log(now);
generateSignature({
t: now,
m: your_qus || ""
}).then(sign => {
console.log(sign)
abortXml = GM_xmlhttpRequest({
method: "POST",
//url: "https://chat.openai.com/backend-api/conversation",
url: "https://chatforai.com/api/generate",
headers: {
"Content-Type": "application/json"
// Authorization: `Bearer `,
},
data: JSON.stringify({
messages: [{
role: "user",
content: your_qus
}],
time: now,
pass: null,
sign: sign
}),
// data: JSON.stringify({
// prompt: "Human:"+your_qus+"\nAI:",
// tokensLength: your_qus.length
// }),
onload: function(res) {
if (res.status === 200) {
console.log('成功....')
console.log(res.response)
let rest = res.response
//console.log(rest.choices[0].text.replaceAll("\n","</br>"))
try {
log(mdConverter(rest.replaceAll(/\\n+/g, "\n")))
document.getElementById('gptAnswer').innerHTML =
`${mdConverter(rest.replaceAll(/\\n+/g,"\n"))}`
} catch (e) {
//TODO handle the exception
document.getElementById('gptAnswer').innerHTML = `${rest}`
}
for (let i = 0; i <= document.getElementsByTagName("code").length -
1; i++) {
document.getElementsByTagName("code")[i].setAttribute("class",
"language-javascript hljs");
hljs.highlightAll() //奇怪,为什么不行
}
} else {
console.log('失败')
console.log(res)
document.getElementById('gptAnswer').innerHTML = '访问失败了'
}
},
responseType: "application/json;charset=UTF-8",
onprogress: function(msg) {
//console.log(msg) //Todo
},
onerror: function(err) {
document.getElementById('gptAnswer').innerHTML =
`<div>some err happends,errinfo :<br>${err}</div>`
},
ontimeout: function(err) {
document.getElementById('gptAnswer').innerHTML =
`<div>Opps!TimeOut,Please try again,errinfo:<br>${err}</div>`
}
});
});
}
function creatBox() {
return new Promise((resolve) => {
var divE = document.createElement('div');
var divId = document.createAttribute("id"); //创建属性
divId.value = 'gptDiv'; //设置属性值
divE.setAttributeNode(divId); //给div添加属性
var pE = document.createElement('p');
var pClass = document.createAttribute('class');
pClass.value = 'textClass';
pE.setAttributeNode(pClass)
var pText = document.createTextNode("chatGPT tools Plus 已启动");
pE.appendChild(pText);
divE.appendChild(pE);
divE.innerHTML = `
<div id="gptInputBox">
<input id="gptInput" type=text><button id="button_GPT" >chat一下</button>
</div>
<div id=gptCueBox>
<p id="gptStatus">  openAI 已就绪,请输入你的问题</p>
<article id="gptAnswer" class="markdown-body"><div id="gptAnswer_inner">chatGPT tools Plus 已启动<div></article>
</div><p></p>`
resolve(divE)
})
}
async function pivElemAddEventAndValue(append_case) {
var search_content
if (append_case === 2) {
search_content = document.getElementById('kw').value
}
if (append_case === 1) {
search_content = document.querySelector(
"#tsf > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input:nth-child(3)"
).value
}
if (append_case === 0) {
search_content = document.getElementsByClassName('b_searchbox')[0].value
}
document.getElementById("gptInput").value = search_content
document.getElementById('button_GPT').addEventListener('click', () => {
your_qus = document.getElementById("gptInput").value
do_it()
})
}
async function appendBox(append_case) {
return new Promise((resolve, reject) => {
creatBox().then((divE) => {
switch (append_case) {
case 0: //bing
if (divE) {
document.getElementById('b_context').prepend(divE)
}
break;
case 1: //google
if (document.getElementsByClassName('TQc1id ')[0]) {
document.getElementsByClassName('TQc1id ')[0].prepend(divE);
} else {
document.getElementById("rcnt").appendChild(divE);
}
break;
case 2:
if (document.getElementById('content_right')) {
document.getElementById('content_right').prepend(divE)
}
break;
default:
if (divE) {
console.log(`啥情况${divE}`)
}
}
}).catch((err) => {
throw new Error(err)
})
resolve("finished")
})
}
//焦点函数
function isBlur() {
var myInput = document.getElementById('gptInput');
if (myInput == document.activeElement) {
return 1
} else {
return 0
}
}
function keyEvent() {
document.onkeydown = function(e) {
var keyNum = window.event ? e.keyCode : e.which;
if (13 == keyNum) {
if (isBlur()) {
document.getElementById('button_GPT').click()
} else {
console.log("失焦不执行")
}
}
}
}
function checkIp() {
GM_xmlhttpRequest({
method: "GET",
url: "http://ip-api.com/json/",
onloadend: function(data) {
if (data) {
try {
data = JSON.parse(data.response)
} catch (err) {
console.log(err)
}
console.log(data.country)
if (data.country == "Hong Kong") {
document.getElementById('gptStatus').innerHTML = `  openAI 已就绪,请输入你的问题`
}
} else {
document.getElementById('gptStatus').innerHTML = `  openAI 就绪`
throw new Error('Error while executing the code');
}
},
onerror: function(err) {
document.getElementById('gptStatus').innerHTML = `  openAI 就绪`
throw new Error('Error while executing the code');
},
ontimeout: function(err) {
document.getElementById('gptStatus').innerHTML = `  openAI 就绪`
throw new Error('Error while executing the code');
}
})
}
function addBothStyle() {
GM_addStyle(`
#dot{
height: 4px;
width: 4px;
display: inline-block;
border-radius: 2px;
animation: dotting 2.4s infinite step-start;
}
@keyframes dotting {
25%{
box-shadow: 4px 0 0 #71777D;
}
50%{
box-shadow: 4px 0 0 #71777D ,14px 0 0 #71777D;
}
75%{
box-shadow: 4px 0 0 #71777D ,14px 0 0 #71777D, 24px 0 0 #71777D;
}
}
pre{
overflow-x: scroll;
overflow-y: hidden;
background: #fffaec;
border-radius: 4px;
padding: 14px 3px;
}
pre::-webkit-scrollbar {
}
`)
}
function getYourCookie() {
GM_xmlhttpRequest({
method: "GET",
url: "https://chat.openai.com/api/auth/session",
onloadend: function(data) {
if (data) {
data = JSON.parse(data.response)
console.log(data.accessToken)
// window.document.cookie=`your_cookie=${data.accessToken};expire:1000*60*60*24`
setCookie("your_cookie", data.accessToken, 1)
}
},
onerror: function(err) {
throw new Error('Error while executing the code');
},
ontimeout: function(err) {
throw new Error('Error while executing the code');
}
})
}
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires;
}
//原生cookie函数
function getCookieObject() {
let cookieString = document.cookie;
cookieString = cookieString.substring(0, cookieString.length - 1);
let tempCookieArray = cookieString.split('; ');
let cookieObject = {}; // 存放 cookie 键值对
tempCookieArray.forEach(item => {
let name = item.substring(0, item.indexOf('='));
let value = item.substring(item.indexOf('=') + 1);
value = decodeURIComponent(value); // 还原字符串
cookieObject[name] = value; // 将键值插入中这个对象中
});
return cookieObject // 返回包含 cookie 键值对的对象
}
function sendModerations() {
GM_xmlhttpRequest({
method: "POST",
url: requestUrl,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${your_cookie}`,
},
data: JSON.stringify({
input: getCookieObject().preQuesAns,
model: "text-moderation-playground"
}),
onloadend: function(data) {
console.log(data)
},
onerror: function(err) {
throw new Error('Error while executing the code');
},
ontimeout: function(err) {
throw new Error('Error while executing the code');
}
})
}
function autoClick() {
document.getElementById('button_GPT').click()
}
function linkToBing_beautification_script() {
if (getCookieObject.blurDeg && getCookieObject.aDeg1 && getCookieObject.aDeg2) {
document.getElementById('gptDiv').style.background = `#ffffff${getCookieObject.aDeg2}`
document.getElementById('gptDiv').style.backdropFilter = `${getCookieObject.blurDeg}`
}
}
function creatBox_and_addEventlis(append_case) {
var divE = document.createElement('div');
var divId = document.createAttribute("id"); //创建属性
divId.value = 'gptDiv'; //设置属性值
divE.setAttributeNode(divId); //给div添加属性
var pE = document.createElement('p');
var pClass = document.createAttribute('class');
pClass.value = 'textClass';
pE.setAttributeNode(pClass)
var pText = document.createTextNode("chatGPT tools Plus 已启动");
pE.appendChild(pText);
divE.appendChild(pE);
switch (append_case) {
case 0:
if (divE) {
document.getElementById('b_context').prepend(divE)
}
break;
case 1:
if (document.getElementsByClassName('TQc1id ')[0]) {
document.getElementsByClassName('TQc1id ')[0].prepend(divE);
} else {
document.getElementById("rcnt").appendChild(divE);
}
break;
case 2:
if (document.getElementById('content_right')) {
document.getElementById('content_right').prepend(divE)
}
break;
default:
if (divE) {
document.getElementById('b_context').prepend(divE)
}
}
document.getElementById('gptDiv').innerHTML =
`<div id="gptInputBox"><input id="gptInput"type=text><button id="button_GPT">chat一下</button></div><div id=gptCueBox><p id="gptStatus">  openAI已就绪,请输入你的问题</p><div id="gptAnswer">chatGPT tools Plus 免费版已启动</div></div><p></p>`
var search_content
if (append_case === 2) {
search_content = document.getElementById('kw').value
}
if (append_case === 1) {
search_content = document.querySelector(
"#tsf > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input:nth-child(3)")
.value
}
if (append_case === 0) {
search_content = document.getElementsByClassName('b_searchbox')[0].value
}
document.getElementById("gptInput").value = search_content
document.getElementById('button_GPT').addEventListener('click', () => {
your_qus = document.getElementById("gptInput").value
do_it()
})
}
function log(a) {
console.log(a)
}
function Uint8ArrayToString(fileData) {
var dataString = "";
for (var i = 0; i < fileData.length; i++) {
dataString += String.fromCharCode(fileData[i]);
}
return dataString
}
function decodeUnicode(str) {
str = str.replace(/\\/g, "%");
//转换中文
str = unescape(str);
//将其他受影响的转换回原来
str = str.replace(/%/g, "\\");
//对网址的链接进行处理
str = str.replace(/\\/g, "");
return str;
}
function mdConverter(rawData) {
var converter = new showdown.Converter(); //增加拓展table
converter.setOption('tables',
true); //启用表格选项。从showdown 1.2.0版开始,表支持已作为可选功能移入核心拓展,showdown.table.min.js扩展已被弃用
var view = converter.makeHtml(rawData);
return view;
}
})();