// ==UserScript==
// @name ChatGPT功能增强_Compatible
// @namespace http://tampermonkey.net/
// @version 1.2.5
// @description 此版本兼容性较好
// @author bigemon; 捈荼
// @match https://chat.openai.com/chat
// @match https://chat.openai.com/chat/*
// @match https://chat.openai.com/auth/login
// @icon https://chat.openai.com/favicon.ico
// @license GPL-3.0
// @run-at document-idie
// @grant none
// ==/UserScript==
function dispose(_alert) {
/*
This file is automatically generated by ChatGPT based on instructions
*/
// to avoid blank interface issues.
const DELAY_TIME = 500;
setTimeout(function () {
// Get the entire page's source code as a string
var pageSource = document.documentElement.outerHTML;
const regex = /\s\"oof\":true\s/;
// Check if the page source contains "oof":true
if (regex.test(pageSource) && !window.oofOverwrite) {
window.oofOverwrite = true;
pageSource = pageSource.replace(/\"oof\":true/g, '"oof":false');
// Replace the current page's source code with the modified version
document.open();
document.write(pageSource);
document.close();
}
}, DELAY_TIME);
window.enableFakeMod = (localStorage.getItem("enable_fakemod") == 'false') ? false : true;
// 创建一个新的style元素
var style = document.createElement('style');
// 在style元素中添加CSS样式
style.innerHTML = '.switch{position:relative;display:inline-block;width:60px;height:34px;}.switch input{opacity:0;width:0;height:0;}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;-webkit-transition:.4s;transition:.4s;}.slider:before{position:absolute;content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:white;-webkit-transition:.4s;transition:.4s;}input:checked + .slider{background-color:#2196F3;}input:focus + .slider{box-shadow:0 0 1px #2196F3;}input:checked + .slider:before{-webkit-transform:translateX(26px);-ms-transform:translateX(26px);transform:translateX(26px);}.slider.round{border-radius:34px;}.slider.round:before{border-radius:50%;}';
// 将style元素添加到页面的head中
document.head.appendChild(style);
window.switchEnableFakeMod = function () {
let cswitch = document.querySelector("input#cswitch");
let checked = cswitch ? cswitch.checked : false;
if (checked) {
window.enableFakeMod = true;
localStorage.setItem("enable_fakemod", true);
} else {
window.enableFakeMod = false;
localStorage.setItem('enable_fakemod', false);
}
};
window.clearAllBoxItem = function () {
let navs = document.querySelectorAll('nav');
for (var x = 0; x < navs.length; x++) {
var allItems = navs[x].querySelectorAll('div.toolbox-item');
for (var i = 0; i < allItems.length; i++) {
allItems[i].remove();
}
}
};
window.exportSaveData = function () {
var conversation_id = window.conversation_id_last || "";
var parent_message_id = window.parent_message_id_last || "";
var authorization = window.authorization_last;
if (conversation_id == "" || parent_message_id == "" || conversation_id == "undefined" || parent_message_id == "undefined") {
alert("请至少说两句话再使用这个功能!");
return
}
var jsonObject = {
conversation_id: conversation_id,
parent_message_id: parent_message_id,
authorization: authorization
};
var jsonString = JSON.stringify(jsonObject);
var base64String = window.btoa(jsonString);
return base64String;
};
window.importSaveData = function (savB64) {
var decodedString = window.atob(savB64);
var jsonObject = JSON.parse(decodedString);
if (!jsonObject || jsonObject.conversation_id === undefined || jsonObject.parent_message_id === undefined) {
alert("会话存档已损坏, 请确保完整复制!");
return
}
let authUnix = window.getAuthTimestamp(jsonObject.authorization) || 0;
if (authUnix && Math.floor(Date.now() / 1000) > authUnix) {
if (!confirm("这个会话存档的Token看起来已过期,或许无法正常工作。\r\n假如这个存档是由当前账号所导出,您可以尝试使用当前会话覆盖导入的状态。\r\n是否继续?")) {
return
}
} else {
alert("这个会话存档的有效期最长至:\r\n" + (new Date(authUnix * 1000)).toLocaleString('en-US') + "\r\n\r\n请注意:导入的会话无法被再次导出,也无法保存");
window.import_authorization = jsonObject.authorization;
}
window.next_conversation_id = jsonObject.conversation_id;
window.next_parent_message_id = jsonObject.parent_message_id;
alert("导入成功,当前会话状态已「暂时」附加到导入的存档。这将对您的下一句话生效。\r\n如果该存档的宿主已退出登录或释放该会话,则存档也会一起失效\r\n此时您可能会被提示登录过期。\r\n\r\n若要中途解除附加状态。请刷新浏览器、点击「 +New chat 」新建会话或切换到其它的会话。");
};
window.clearTempValues = function () {
delete window.import_authorization;
delete window.next_parent_message_id;
delete window.next_conversation_id;
delete window.parent_message_id_last;
delete window.conversation_id_last;
delete window.authorization_last;
};
window.boxInit = function () {
window.clearAllBoxItem();
var navs = document.querySelectorAll('nav');
for (var x = 0; x < navs.length; x++) {
let nav = navs[x];
let switchLabel = document.createElement("div");
let aEle = nav.querySelectorAll('a');
if (!nav.childNodes[0].hasOwnProperty('patched')) {
nav.childNodes[0].addEventListener("click", function (event) {
event.preventDefault();
if (confirm("即将创建新的会话, 使用导入功能导入的会话将失效,是否继续?")) {
nav.childNodes[0].removeEventListener('click', arguments.callee);
window.clearTempValues();
nav.childNodes[0].click();
}
});
Object.defineProperty(nav.childNodes[0], 'patched', { value: true, enumerable: false });
}
switchLabel.setAttribute("class", "toolbox-item flex py-3 px-3 items-center gap-3 rounded-md hover:bg-gray-500/10 transition-colors duration-200 text-white cursor-pointer text-sm flex-shrink-0 border border-white/20");
switchLabel.innerHTML = `<svg t="1670527970700" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9830" width="18" height="18"><path d="M514 114.3c-219.9 0-398.8 178.9-398.8 398.8 0 220 178.9 398.9 398.8 398.9s398.8-178.9 398.8-398.8S733.9 114.3 514 114.3z m0 685.2c-42 0-76.1-34.1-76.1-76.1 0-42 34.1-76.1 76.1-76.1 42 0 76.1 34.1 76.1 76.1 0 42.1-34.1 76.1-76.1 76.1z m0-193.8c-50.7 0-91.4-237-91.4-287.4 0-50.5 41-91.4 91.5-91.4s91.4 40.9 91.4 91.4c-0.1 50.4-40.8 287.4-91.5 287.4z" p-id="9831" fill="#dbdbdb"></path></svg>禁用数据监管<label class="switch" style="position: absolute; right: 15px;"><input id="cswitch" type="checkbox" ${window.enableFakeMod ? "checked='true'" : ""} onclick="window.switchEnableFakeMod()" ><span class="slider"></span></label>`;
nav.insertBefore(switchLabel, nav.childNodes[1]); // 在 nav 元素的第二个子元素之前插入新建的 switchLabel 元素
for (var i = 0; i < aEle.length; i++) {
if (aEle[i].innerHTML.indexOf('FAQ') >= 0) {
aEle[i].removeAttribute('href');
aEle[i].innerHTML = '<svg t="1670527911492" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8753" width="16" height="16"><path d="M562.996016 643.229748V72.074369a50.996016 50.996016 0 0 0-101.992032 0v571.155379a50.996016 50.996016 0 0 0 101.992032 0z" fill="#dbdbdb" p-id="8754"></path><path d="M513.087915 144.080744L802.337317 432.446215a50.996016 50.996016 0 0 0 71.93838-72.210358L513.087915 0 149.588313 362.411687A50.996016 50.996016 0 0 0 221.594688 434.486056L513.087915 144.148738zM53.035857 643.229748v184.537583c0 109.471448 105.255777 192.832935 230.026029 192.832935h457.876228c124.770252 0 230.026029-83.361487 230.026029-192.832935V643.229748a50.996016 50.996016 0 1 0-101.992031 0v184.537583c0 47.256308-55.075697 90.840903-128.033998 90.840903H283.061886c-72.9583 0-128.033997-43.65259-128.033998-90.840903V643.229748a50.996016 50.996016 0 0 0-101.992031 0z" fill="#dbdbdb" p-id="8755"></path></svg>导出会话';
aEle[i].onclick = function () {
var textarea = document.querySelector("textarea");
let savB64 = window.exportSaveData();
if (savB64) {
prompt("↓请复制您的会话存档↓", savB64);
}
}
}
if (aEle[i].innerHTML.indexOf('OpenAI Discord') >= 0) {
aEle[i].removeAttribute('href');
aEle[i].innerHTML = '<svg t="1670527878930" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7606" width="16" height="16"><path d="M563.2 68.266667v573.44a51.2 51.2 0 0 1-102.4 0V68.266667a51.2 51.2 0 0 1 102.4 0z" fill="#dbdbdb" p-id="7607"></path><path d="M513.092267 616.584533l290.474666-289.518933a51.2 51.2 0 0 1 72.226134 72.4992L513.092267 761.173333 148.138667 397.448533A51.2 51.2 0 0 1 220.433067 324.949333l292.6592 291.6352z" fill="#dbdbdb" p-id="7608"></path><path d="M51.2 641.706667v185.275733c0 109.909333 105.6768 193.604267 230.946133 193.604267h459.707734c125.269333 0 230.946133-83.694933 230.946133-193.604267V641.706667a51.2 51.2 0 1 0-102.4 0v185.275733c0 47.445333-55.296 91.204267-128.546133 91.204267H282.146133c-73.250133 0-128.546133-43.8272-128.546133-91.204267V641.706667a51.2 51.2 0 0 0-102.4 0z" fill="#dbdbdb" p-id="7609"></path></svg>导入会话';
aEle[i].onclick = function () {
if (!window.location.href.includes("/chat/") && window.location.href.includes("/chat")) {
alert("请在一个您已经存在的会话使用这个功能,\r\n而不是在「 New Chat 」的空会话上下文里附加");
return
}
var userInput = prompt("请在此粘贴会话存档");
window.importSaveData(userInput);
}
}
if (!nav.childNodes[0].hasOwnProperty('patched')) {
nav.childNodes[0].addEventListener("click", function (event) {
event.preventDefault();
if (confirm("即将创建新的会话, 使用导入功能导入的会话将失效,是否继续?")) {
nav.childNodes[0].removeEventListener('click', arguments.callee);
window.clearTempValues();
nav.childNodes[0].click();
}
});
Object.defineProperty(nav.childNodes[0], 'patched', { value: true, enumerable: false });
}
}
}
};
window.getAuthTimestamp = function (authBearer) {
var authArray = authBearer.split('.');
if (authArray.length < 2) {
return 0;
}
var decodedString = window.atob(authArray[1]);
var jsonObject = JSON.parse(decodedString);
if (jsonObject && jsonObject.exp) {
return jsonObject.exp;
}
return 0;
};
window.boxInit();
const oldFetch = window.fetch;
window.fetch = function (...args) {
if (args[0].includes("moderations") && window.enableFakeMod) {
return new Response('{}', {
status: 200,
statusText: "ok",
})
}
if (args[0].includes("signout") && window.enableFakeMod) {
if (!confirm("是否要退出登录?")) {
return new Response('{}', {
status: 200,
statusText: "ok",
})
}
}
if (args[0].includes("/conversation/") || args[0].includes("/conversations") || args[0].includes("/chat.json")) {
if (args[0].includes("/conversations") && args[1].method === "PATCH") {
let bodyJson = JSON.parse(args[1].body);
bodyJson.is_visible = !(confirm("警告:真的要清空您账户下所有的会话记录?") && confirm("警告:第二次确认,清空后您将无法找回之前的所有记录!是否继续?"));
if (!bodyJson.is_visible) {
window.clearTempValues();
}
args[1].body = JSON.stringify(bodyJson);
}
setTimeout(window.onresize, 1000);
window.clearTempValues();
} else if (args[0].includes("conversation")) {
if (args[1].body && args[1].method === "POST") {
//覆盖原始鉴权
var headers = new Headers(args[1].headers);
let lastAuth = headers.get("authorization");
window.authorization_last = lastAuth;
let authorization = window.import_authorization ? window.import_authorization : lastAuth;
headers.set("authorization", authorization);
args[1].headers = headers;
//处理会话数据附加
if (window.next_conversation_id && window.next_parent_message_id) {
let bodyJson = JSON.parse(args[1].body);
bodyJson.conversation_id = window.next_conversation_id ? window.next_conversation_id : bodyJson.conversation_id;
bodyJson.parent_message_id = window.next_parent_message_id ? window.next_parent_message_id : bodyJson.parent_message_id;
args[1].body = JSON.stringify(bodyJson);
delete window.next_parent_message_id;
delete window.next_conversation_id;
} else {
let bodyJson = JSON.parse(args[1].body);
window.conversation_id_last = bodyJson.conversation_id;
window.parent_message_id_last = bodyJson.parent_message_id;
}
}
}
return oldFetch(...args)
};
var resizeTimer = null;
window.onresize = function () {
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
window.boxInit();
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
if (button.innerHTML.indexOf('sidebar') !== -1) {
button.addEventListener('click', function () { window.setTimeout(function () { window.boxInit() }, 300) });
}
}
}, 200);
};
window.onresize();
_alert("赛博工具娘v1.1.13脚本已启用。本工具由ChatGPT在指导下生成~\r\n\r\n更新:\r\n\r\n1. 为清空会话、退出登录以及导入会话做了防呆设计 \r\n\r\n2. 新增oof状态重载。当服务器高负载时:\r\n ·「Regenerate Response」将强制启用\r\n · 禁止登录时,可以通过加载脚本直接登录。");
}
(function () {
const SCRIPT_VERSION = GM_info.version;
const storageVersion = localStorage.getItem('__tm_savedVersion');
const storageDate = localStorage.getItem('__tm_savedDate');
const dateNow = new Date().getTime();
if ((storageVersion == null || storageDate == null || storageVersion < SCRIPT_VERSION || dateNow - storageDate > 2592000000)
&& (!location.href.includes('auth'))) {
dispose(alert);
localStorage.setItem('__tm_savedVersion', SCRIPT_VERSION);
localStorage.setItem('__tm_savedDate', dateNow);
} else dispose(function(){});
})();