🏠 Home 

Greasy Fork is available in English.

🚀🚀GPT4直连账号切换🚀🚀

为GPT4直连账号切换提供便利


安装此脚本?
// ==UserScript==
// @name         🚀🚀GPT4直连账号切换🚀🚀
// @namespace    gpt4-account-switch
// @version      0.0.6
// @description  为GPT4直连账号切换提供便利
// @author       LLinkedList771
// @run-at       document-end
// @match        https://gpt4.xn--fiqq6k90ovivepbxtg0bz10m.xyz/*
// @match        https://chat.freegpts.org/*
// @homepageURL  https://github.com/linkedlist771/GPT4-Account-Switch
// @supportURL   https://github.com/linkedlist771/GPT4-Account-Switch/issues
// @license      MIT
// ==/UserScript==
(function () {
"use strict";
let accountData = null;
console.log("GPT4-Account-Switch 脚本正在运行");
function setAccountData(data) {
accountData = data;
}
function clearPreviousAccountData() {
// 清除内存中的账号数据
accountData = null;
localStorage.removeItem("gpt4_account_json");
const switchDiv = document.querySelector(".tools-logger-panel .switch");
if (switchDiv) {
while (switchDiv.firstChild) {
switchDiv.removeChild(switchDiv.firstChild);
}
}
}
function isValidEmail(email) {
// 使用正则表达式验证电子邮件地址
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// ----------------- Styles -----------------
function addStyles() {
const styles = `
.tools-logger-panel {
position: fixed;
top: 10%;
right: 2%;
background-color: white;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
z-index: 9999;
width: 250px;
}
.tools-logger-panel.minimized {
width: auto;
padding: 5px;
}
.switch.minimized {
display: none;
}
.head {
font-weight: bold;
margin-bottom: 10px;
}
.switch
display: inline-block;
vertical-align: middle;
}
.close {
cursor: pointer;
}
.loadAccountJsonBtn {
border: 1px solid #ccc;
border-radius: 5px;
text-decoration: underline;
}
.account-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 10px;
}
.account-btn {
padding: 5px 10px;
margin: 2px 0;
background-color: #f0f0f0;
font-weight: bold;
}
.email-display {
font-size: 0.8em;
color: #666;
margin-top: 2px;
}
.latex-toggle {
cursor: pointer;
float:right;
margin-right:5px;
}
.latex-toggle.minimized::before {
content: "[+]";
}
.latex-toggle.maximized::before {
content: "[-]";
}
`;
const styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText = styles;
document.head.appendChild(styleSheet);
}
// ----------------- UI Creation -----------------
function createUI() {
const controlDiv = document.createElement("div");
controlDiv.className = "tools-logger-panel";
controlDiv.innerHTML = `
<div class="head">
<span class="title">GPT4账号切换助手</span>
<span class="latex-toggle maximized"></span>
</div>
<div class="main">
<button id="loadAccountJsonBtn">导入账号信息</button>
</div>
<div class="switch">
</div>
`;
document.body.appendChild(controlDiv);
// controlDiv.querySelector(".close").onclick = function() {
//     controlDiv.remove();
// };
const toggleIcon = controlDiv.querySelector(".latex-toggle");
const title = controlDiv.querySelector(".title");
const switchDiv = controlDiv.querySelector(".switch");
toggleIcon.onclick = function () {
if (toggleIcon.classList.contains("maximized")) {
controlDiv.querySelector(".main").style.display = "none";
title.style.display = "none";
toggleIcon.classList.remove("maximized");
toggleIcon.classList.add("minimized");
controlDiv.classList.add("minimized");
switchDiv.classList.add("minimized");
} else {
controlDiv.querySelector(".main").style.display = "block";
title.style.display = "inline-block";
toggleIcon.classList.remove("minimized");
toggleIcon.classList.add("maximized");
controlDiv.classList.remove("minimized");
switchDiv.classList.remove("minimized");
}
saveSettings(controlDiv); // Save settings when panel state is changed
};
// 添加文件输入元素
const fileInput = document.createElement("input");
fileInput.type = "file";
fileInput.accept = ".json";
fileInput.style.display = "none";
controlDiv.appendChild(fileInput);
// 为导入账号信息按钮添加点击事件监听器
document
.getElementById("loadAccountJsonBtn")
.addEventListener("click", function () {
fileInput.click();
});
// 监听文件选择事件
fileInput.addEventListener("change", function (event) {
const file = event.target.files[0];
// 创建FileReader对象
const reader = new FileReader();
// 监听文件读取完成事件
reader.onload = function (event) {
try {
const jsonData = JSON.parse(event.target.r###lt);
// 在这里处理获取到的JSON数据
console.log(jsonData);
processAccountJsonData(jsonData);
// 可以在这里执行其他操作,如在页面上显示数据等
} catch (error) {
console.error("Error parsing JSON:", error);
}
};
// 读取文件内容为文本
reader.readAsText(file);
});
loadSettings(controlDiv); // Load settings when panel is created
}
// 获取当前的url的(去掉路由)
function getCurrentUrl() {
const targetURLBase =
window.location.protocol + "//" + window.location.host;
return targetURLBase;
}
function redirectToBaseUrl() {
// https://gpt4.xn--fiqq6k90ovivepbxtg0bz10m.xyz/auth/login
console.log("Log in");
const targetURLBase = getCurrentUrl();
window.location.href = targetURLBase;
}
function logOutCurrentAccount(accessToken) {
const targetURLBase = getCurrentUrl();
const logoutURL = targetURLBase + "/auth/logout";
window.location.href = logoutURL;
}
function logInNewAccount(userName, passWork) {
// var loginBtn = document.querySelector('#submit');
// if(loginBtn) {
//     loginBtn.click();
// }
// 第一个输入id="username" 填入userName
var userNameArea = document.getElementById("username");
if (userNameArea) {
userNameArea.value = userName; // 将 '你的用户名' 替换为你想要输入的内容
}
// 第二个输入id="password" 填入passWork
var passWordArea = document.getElementById("password");
if (passWordArea) {
passWordArea.value = passWork; // 将 '你的密码' 替换为你想要输入的内容
}
// 找到登录按钮
var loginBtn = document.querySelector('button[type="submit"]');
if (loginBtn) {
loginBtn.click();
}
// // 找到button里面的值(innerHtml)为OK的按钮
// var okBtn = Array.from(document.querySelectorAll('button')).find(function(btn) {
//     return btn.innerText.trim() === 'OK';
// });
// if(okBtn) {
//     okBtn.click();
// }
}
function processAccountJsonData(jsonData) {
// 检查所有键是否都是有效的电子邮件
const allKeysAreValid = Object.keys(jsonData).every(isValidEmail);
if (allKeysAreValid) {
clearPreviousAccountData(); // 调用清理函数
localStorage.setItem("gpt4_account_json", JSON.stringify(jsonData));
setAccountData(jsonData);
creatSwitchBtnUI(); // 确保此时已经有有效的accountData来创建按钮
} else {
alert("Some entries are invalid. Please check the data.");
}
}
function alertLoadAccountData() {
alert("请先导入账号信息");
}
function retriveAccountData() {
// 1.首先判断当前的accountData是否为空
if (accountData !== null) {
return true;
}
// 2.从localStorage中读取数据
const jsonData = localStorage.getItem("gpt4_account_json");
if (jsonData !== null) {
accountData = JSON.parse(jsonData);
return true;
}
// 如果当前的accountData为空, 但是localStoraage也为空, 则提示当前需要加载账号信息
alertLoadAccountData();
return false;
}
// ----------------- Save and Load Settings -----------------
function saveSettings(controlDiv) {
const panelState = controlDiv.classList.contains("minimized")
? "minimized"
: "maximized";
localStorage.setItem("gpt4PanelState", panelState);
}
function loadSettings(controlDiv) {
const panelState = localStorage.getItem("gpt4PanelState");
const toggleIcon = controlDiv.querySelector(".latex-toggle");
const title = controlDiv.querySelector(".title");
const switchDiv = controlDiv.querySelector(".switch");
if (panelState === "minimized") {
controlDiv.querySelector(".main").style.display = "none";
title.style.display = "none";
toggleIcon.classList.remove("maximized");
toggleIcon.classList.add("minimized");
controlDiv.classList.add("minimized");
switchDiv.classList.add("minimized");
} else {
controlDiv.querySelector(".main").style.display = "block";
title.style.display = "inline-block";
toggleIcon.classList.remove("minimized");
toggleIcon.classList.add("maximized");
controlDiv.classList.remove("minimized");
switchDiv.classList.remove("minimized");
}
}
function creatSwitchBtnUI() {
const controlDiv = document.querySelector(".tools-logger-panel .switch");
if (!controlDiv) return;
let button = document.createElement("button");
button.className = "account-btn";
button.textContent = `登出账号`;
button.onclick = () => {
// Logic to switch accounts
// setAccountData(accountData[key]);
logOutCurrentAccount();
console.log("Switched to account:", accountData[key]);
};
controlDiv.appendChild(button);
//                 redirectToBaseUrl();
button = document.createElement("button");
button.className = "account-btn";
button.textContent = `登录账号`;
button.onclick = () => {
// Logic to switch accounts
// setAccountData(accountData[key]);
redirectToBaseUrl();
console.log("Switched to account:", accountData[key]);
};
controlDiv.appendChild(button);
Object.keys(accountData).forEach((email, index) => {
// 创建包含按钮和电子邮件地址的容器
const container = document.createElement("div");
container.className = "account-container";
// 创建登录按钮
const button = document.createElement("button");
button.className = "account-btn";
button.textContent = `登录账号${index + 1}`;
button.onclick = () => {
logInNewAccount(email, accountData[email]);
console.log("Switched to account:", email);
};
// 创建显示电子邮件地址的元素
const emailDisplay = document.createElement("span");
emailDisplay.className = "email-display";
emailDisplay.textContent = email;
// 将按钮和电子邮件地址添加到容器
container.appendChild(button);
container.appendChild(emailDisplay);
// 将容器添加到主DIV
controlDiv.appendChild(container);
});
}
function loadAndCreateAccountSwitchBtnUI() {
// 首先判断localStorage中是否有数据
if (!retriveAccountData()) {
return;
}
creatSwitchBtnUI(); // Create switch buttons based on account data
// 现在开始加载UI
}
function init() {
// try to find 'account-btn';
// if found, then return;
console.log("try to init");
const accountBtn = document.querySelector(".account-btn");
if (accountBtn) {
console.log("account-btn found");
return;
}
console.log("account-btn not found");
addStyles();
createUI();
loadAndCreateAccountSwitchBtnUI(); // Ensure the switch buttons are created after UI is loaded and data is retrieved
}
// set time interval to check if the element is loaded
setInterval(function () {
if (document.querySelector(".tools-logger-panel")) {
} else {
init();
}
}, 1000);
})();