Add initial implementation of Cursor Pro Keep Alive tool
- Created .gitignore to exclude unnecessary files. - Added config.ini for account configuration. - Implemented cursor_auth_manager.py for managing authentication. - Developed cursor_pro_keep_alive.py for automated account management. - Included CursorKeepAlive.spec for packaging. - Added gpt-accesstoken.py for obtaining ChatGPT access tokens. - Created README.md with usage instructions. - Updated requirements.txt with necessary dependencies. - Added run_cursor.bat for script execution. - Implemented update_cursor_auth.py for updating authentication details. - Included turnstilePatch for handling CAPTCHA challenges. - Added logging functionality in log.txt for tracking script execution. - Created dist folder with packaged executable and necessary files.
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.idea
|
||||
__pycache__
|
||||
|
||||
build
|
||||
42
CursorKeepAlive.spec
Normal file
42
CursorKeepAlive.spec
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
a = Analysis(
|
||||
['cursor_pro_keep_alive.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[
|
||||
('config.ini', '.'),
|
||||
('turnstilePatch', 'turnstilePatch'),
|
||||
('cursor_auth_manager.py', '.'),
|
||||
],
|
||||
hiddenimports=[
|
||||
'cursor_auth_manager'
|
||||
],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='cursor_pro_keep_alive',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# gpt-cursor-auto
|
||||
Python脚本 一键获取 ChatGpt 的 Access Token -- gpt-accesstoken.py
|
||||
***********************************************************************************************
|
||||
Python脚本 一键获取 Cursor Pro 自动保活 -- cursor_pro_keep_alive.py
|
||||
2024.12.14日 新增自动获取token,无需再手动登录账号关联Cursor,需要 依赖 cursor_auth_manager.py
|
||||
5
config.ini
Normal file
5
config.ini
Normal file
@@ -0,0 +1,5 @@
|
||||
[Account]
|
||||
email = apxeme@mailto.plus
|
||||
password = ccz14321@
|
||||
first_name = cheng
|
||||
last_name = zhen
|
||||
60
cursor_auth_manager.py
Normal file
60
cursor_auth_manager.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import sqlite3
|
||||
import os
|
||||
|
||||
class CursorAuthManager:
|
||||
"""Cursor认证信息管理器"""
|
||||
|
||||
def __init__(self):
|
||||
# 判断操作系统
|
||||
if os.name == 'nt': # Windows
|
||||
self.db_path = os.path.join(os.getenv('APPDATA'), 'Cursor', 'User', 'globalStorage', 'state.vscdb')
|
||||
else: # macOS
|
||||
self.db_path = os.path.expanduser('~/Library/Application Support/Cursor/User/globalStorage/state.vscdb')
|
||||
|
||||
|
||||
def update_auth(self, email=None, access_token=None, refresh_token=None):
|
||||
"""
|
||||
更新Cursor的认证信息
|
||||
:param email: 新的邮箱地址
|
||||
:param access_token: 新的访问令牌
|
||||
:param refresh_token: 新的刷新令牌
|
||||
:return: bool 是否成功更新
|
||||
"""
|
||||
updates = []
|
||||
if email is not None:
|
||||
updates.append(('cursorAuth/cachedEmail', email))
|
||||
if access_token is not None:
|
||||
updates.append(('cursorAuth/accessToken', access_token))
|
||||
if refresh_token is not None:
|
||||
updates.append(('cursorAuth/refreshToken', refresh_token))
|
||||
|
||||
if not updates:
|
||||
print("没有提供任何要更新的值")
|
||||
return False
|
||||
|
||||
conn = None
|
||||
try:
|
||||
conn = sqlite3.connect(self.db_path)
|
||||
cursor = conn.cursor()
|
||||
|
||||
for key, value in updates:
|
||||
query = "UPDATE itemTable SET value = ? WHERE key = ?"
|
||||
cursor.execute(query, (value, key))
|
||||
|
||||
if cursor.rowcount > 0:
|
||||
print(f"成功更新 {key.split('/')[-1]}")
|
||||
else:
|
||||
print(f"未找到 {key.split('/')[-1]} 或值未变化")
|
||||
|
||||
conn.commit()
|
||||
return True
|
||||
|
||||
except sqlite3.Error as e:
|
||||
print("数据库错误:", str(e))
|
||||
return False
|
||||
except Exception as e:
|
||||
print("发生错误:", str(e))
|
||||
return False
|
||||
finally:
|
||||
if conn:
|
||||
conn.close()
|
||||
453
cursor_pro_keep_alive.py
Normal file
453
cursor_pro_keep_alive.py
Normal file
@@ -0,0 +1,453 @@
|
||||
from DrissionPage import ChromiumOptions, Chromium
|
||||
from DrissionPage.common import Keys
|
||||
import re
|
||||
import time
|
||||
import random
|
||||
from cursor_auth_manager import CursorAuthManager
|
||||
from configparser import ConfigParser
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def load_config():
|
||||
"""加载配置文件"""
|
||||
config = ConfigParser()
|
||||
|
||||
# 获取程序运行的根目录
|
||||
root_dir = os.getcwd()
|
||||
config_path = os.path.join(root_dir, "config.ini")
|
||||
|
||||
if os.path.exists(config_path):
|
||||
config.read(config_path, encoding="utf-8")
|
||||
print(f"已加载配置文件: {config_path}")
|
||||
return {
|
||||
"account": config["Account"]["email"],
|
||||
"password": config["Account"]["password"],
|
||||
"first_name": config["Account"]["first_name"],
|
||||
"last_name": config["Account"]["last_name"],
|
||||
}
|
||||
|
||||
raise FileNotFoundError(
|
||||
f"配置文件不存在: {config_path}\n请确保配置文件在程序运行目录下"
|
||||
)
|
||||
|
||||
|
||||
def get_veri_code(tab):
|
||||
"""获取验证码"""
|
||||
username = account.split("@")[0]
|
||||
try:
|
||||
while True:
|
||||
if tab.ele("@id=pre_button"):
|
||||
tab.actions.click("@id=pre_button").type(Keys.CTRL_A).key_down(
|
||||
Keys.BACKSPACE
|
||||
).key_up(Keys.BACKSPACE).input(username).key_down(Keys.ENTER).key_up(
|
||||
Keys.ENTER
|
||||
)
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
while True:
|
||||
new_mail = tab.ele("@class=mail")
|
||||
if new_mail:
|
||||
if new_mail.text:
|
||||
print("最新的邮件:", new_mail.text)
|
||||
tab.actions.click("@class=mail")
|
||||
break
|
||||
else:
|
||||
print(new_mail)
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
if tab.ele("@class=overflow-auto mb-20"):
|
||||
email_content = tab.ele("@class=overflow-auto mb-20").text
|
||||
verification_code = re.search(
|
||||
r"verification code is (\d{6})", email_content
|
||||
)
|
||||
if verification_code:
|
||||
code = verification_code.group(1)
|
||||
print("验证码:", code)
|
||||
else:
|
||||
print("未找到验证码")
|
||||
|
||||
if tab.ele("@id=delete_mail"):
|
||||
tab.actions.click("@id=delete_mail")
|
||||
time.sleep(1)
|
||||
|
||||
if tab.ele("@id=confirm_mail"):
|
||||
tab.actions.click("@id=confirm_mail")
|
||||
print("删除邮件")
|
||||
tab.close()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
return code
|
||||
|
||||
|
||||
def handle_turnstile(tab):
|
||||
"""处理 Turnstile 验证"""
|
||||
print("准备处理验证")
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
challengeCheck = (
|
||||
tab.ele("@id=cf-turnstile", timeout=2)
|
||||
.child()
|
||||
.shadow_root.ele("tag:iframe")
|
||||
.ele("tag:body")
|
||||
.sr("tag:input")
|
||||
)
|
||||
|
||||
if challengeCheck:
|
||||
print("验证框加载完成")
|
||||
time.sleep(random.uniform(1, 3))
|
||||
challengeCheck.click()
|
||||
print("验证按钮已点击,等待验证完成...")
|
||||
time.sleep(2)
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
if tab.ele("@name=password"):
|
||||
print("无需验证")
|
||||
break
|
||||
if tab.ele("@data-index=0"):
|
||||
print("无需验证")
|
||||
break
|
||||
if tab.ele("Account Settings"):
|
||||
print("无需验证")
|
||||
break
|
||||
|
||||
time.sleep(random.uniform(1, 2))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("跳过验证")
|
||||
return False
|
||||
|
||||
|
||||
def delete_account(browser, tab):
|
||||
"""删除账户流程"""
|
||||
print("\n开始删除账户...")
|
||||
|
||||
try:
|
||||
if tab.ele("@name=email"):
|
||||
tab.ele("@name=email").input(account)
|
||||
print("输入账号")
|
||||
time.sleep(random.uniform(1, 3))
|
||||
except Exception as e:
|
||||
print(f"输入账号失败: {str(e)}")
|
||||
|
||||
try:
|
||||
if tab.ele("Continue"):
|
||||
tab.ele("Continue").click()
|
||||
print("点击Continue")
|
||||
except Exception as e:
|
||||
print(f"点击Continue失败: {str(e)}")
|
||||
|
||||
handle_turnstile(tab)
|
||||
time.sleep(5)
|
||||
|
||||
try:
|
||||
if tab.ele("@name=password"):
|
||||
tab.ele("@name=password").input(password)
|
||||
print("输入密码")
|
||||
time.sleep(random.uniform(1, 3))
|
||||
except Exception as e:
|
||||
print("输入密码失败")
|
||||
|
||||
sign_in_button = tab.ele(
|
||||
"xpath:/html/body/div[1]/div/div/div[2]/div/form/div/button"
|
||||
)
|
||||
try:
|
||||
if sign_in_button:
|
||||
sign_in_button.click(by_js=True)
|
||||
print("点击Sign in")
|
||||
except Exception as e:
|
||||
print(f"点击Sign in失败: {str(e)}")
|
||||
|
||||
handle_turnstile(tab)
|
||||
|
||||
# 处理验证码
|
||||
while True:
|
||||
try:
|
||||
if tab.ele("Account Settings"):
|
||||
break
|
||||
if tab.ele("@data-index=0"):
|
||||
tab_mail = browser.new_tab(mail_url)
|
||||
browser.activate_tab(tab_mail)
|
||||
print("打开邮箱页面")
|
||||
code = get_veri_code(tab_mail)
|
||||
|
||||
if code:
|
||||
print("获取验证码成功:", code)
|
||||
browser.activate_tab(tab)
|
||||
else:
|
||||
print("获取验证码失败,程序退出")
|
||||
return False
|
||||
|
||||
i = 0
|
||||
for digit in code:
|
||||
tab.ele(f"@data-index={i}").input(digit)
|
||||
time.sleep(random.uniform(0.1, 0.3))
|
||||
i += 1
|
||||
break
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
handle_turnstile(tab)
|
||||
time.sleep(random.uniform(1, 3))
|
||||
# tab.get_screenshot('sign-in_success.png')
|
||||
# print("登录账户截图")
|
||||
|
||||
tab.get(settings_url)
|
||||
print("进入设置页面")
|
||||
|
||||
try:
|
||||
if tab.ele("@class=mt-1"):
|
||||
tab.ele("@class=mt-1").click()
|
||||
print("点击Adavance")
|
||||
time.sleep(random.uniform(1, 2))
|
||||
except Exception as e:
|
||||
print(f"点击Adavance失败: {str(e)}")
|
||||
|
||||
try:
|
||||
if tab.ele("Delete Account"):
|
||||
tab.ele("Delete Account").click()
|
||||
print("点击Delete Account")
|
||||
time.sleep(random.uniform(1, 2))
|
||||
except Exception as e:
|
||||
print(f"点击Delete Account失败: {str(e)}")
|
||||
|
||||
try:
|
||||
if tab.ele("tag:input"):
|
||||
tab.actions.click("tag:input").type("delete")
|
||||
print("输入delete")
|
||||
time.sleep(random.uniform(1, 2))
|
||||
except Exception as e:
|
||||
print(f"输入delete失败: {str(e)}")
|
||||
|
||||
delete_button = tab.ele(
|
||||
"xpath:/html/body/main/div/div/div/div/div/div[1]/div[2]/div[3]/div[2]/div/div/div[2]/button[2]"
|
||||
)
|
||||
try:
|
||||
if delete_button:
|
||||
print("点击Delete")
|
||||
delete_button.click()
|
||||
time.sleep(5)
|
||||
# tab.get_screenshot('delete_account.png')
|
||||
# print("删除账户截图")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"点击Delete失败: {str(e)}")
|
||||
return False
|
||||
|
||||
|
||||
def get_cursor_session_token(tab):
|
||||
"""获取cursor session token"""
|
||||
cookies = tab.cookies()
|
||||
cursor_session_token = None
|
||||
for cookie in cookies:
|
||||
if cookie["name"] == "WorkosCursorSessionToken":
|
||||
cursor_session_token = cookie["value"].split("%3A%3A")[1]
|
||||
break
|
||||
return cursor_session_token
|
||||
|
||||
|
||||
def update_cursor_auth(email=None, access_token=None, refresh_token=None):
|
||||
"""
|
||||
更新Cursor的认证信息的便捷函数
|
||||
"""
|
||||
auth_manager = CursorAuthManager()
|
||||
return auth_manager.update_auth(email, access_token, refresh_token)
|
||||
|
||||
|
||||
def sign_up_account(browser, tab):
|
||||
"""注册账户流程"""
|
||||
print("\n开始注册新账户...")
|
||||
tab.get(sign_up_url)
|
||||
|
||||
try:
|
||||
if tab.ele("@name=first_name"):
|
||||
print("已打开注册页面")
|
||||
tab.actions.click("@name=first_name").input(first_name)
|
||||
time.sleep(random.uniform(1, 3))
|
||||
|
||||
tab.actions.click("@name=last_name").input(last_name)
|
||||
time.sleep(random.uniform(1, 3))
|
||||
|
||||
tab.actions.click("@name=email").input(account)
|
||||
print("输入邮箱")
|
||||
time.sleep(random.uniform(1, 3))
|
||||
|
||||
tab.actions.click("@type=submit")
|
||||
print("点击注册按钮")
|
||||
|
||||
except Exception as e:
|
||||
print("打开注册页面失败")
|
||||
return False
|
||||
|
||||
handle_turnstile(tab)
|
||||
|
||||
try:
|
||||
if tab.ele("@name=password"):
|
||||
tab.ele("@name=password").input(password)
|
||||
print("输入密码")
|
||||
time.sleep(random.uniform(1, 3))
|
||||
|
||||
tab.ele("@type=submit").click()
|
||||
print("点击Continue按钮")
|
||||
|
||||
except Exception as e:
|
||||
print("输入密码失败")
|
||||
return False
|
||||
|
||||
time.sleep(random.uniform(1, 3))
|
||||
if tab.ele("This email is not available."):
|
||||
print("This email is not available.")
|
||||
return False
|
||||
|
||||
handle_turnstile(tab)
|
||||
|
||||
while True:
|
||||
try:
|
||||
if tab.ele("Account Settings"):
|
||||
break
|
||||
if tab.ele("@data-index=0"):
|
||||
tab_mail = browser.new_tab(mail_url)
|
||||
browser.activate_tab(tab_mail)
|
||||
print("打开邮箱页面")
|
||||
code = get_veri_code(tab_mail)
|
||||
|
||||
if code:
|
||||
print("获取验证码成功:", code)
|
||||
browser.activate_tab(tab)
|
||||
else:
|
||||
print("获取验证码失败,程序退出")
|
||||
return False
|
||||
|
||||
i = 0
|
||||
for digit in code:
|
||||
tab.ele(f"@data-index={i}").input(digit)
|
||||
time.sleep(random.uniform(0.1, 0.3))
|
||||
i += 1
|
||||
break
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
handle_turnstile(tab)
|
||||
|
||||
time.sleep(random.uniform(1, 3))
|
||||
print("进入设置页面")
|
||||
tab.get(settings_url)
|
||||
try:
|
||||
usage_ele = tab.ele(
|
||||
"xpath:/html/body/main/div/div/div/div/div/div[2]/div/div/div/div[1]/div[1]/span[2]"
|
||||
)
|
||||
if usage_ele:
|
||||
usage_info = usage_ele.text
|
||||
total_usage = usage_info.split("/")[-1].strip()
|
||||
print("可用上限: " + total_usage)
|
||||
except Exception as e:
|
||||
print("获取可用上限失败")
|
||||
# tab.get_screenshot("sign_up_success.png")
|
||||
# print("注册账户截图")
|
||||
print("注册完成")
|
||||
print("Cursor 账号: " + account)
|
||||
print(" 密码: " + password)
|
||||
return True
|
||||
|
||||
|
||||
def get_extension_path():
|
||||
"""获取插件路径"""
|
||||
root_dir = os.getcwd()
|
||||
extension_path = os.path.join(root_dir, "turnstilePatch")
|
||||
|
||||
if hasattr(sys, "_MEIPASS"):
|
||||
print("运行在打包环境中")
|
||||
extension_path = os.path.join(sys._MEIPASS, "turnstilePatch")
|
||||
|
||||
print(f"尝试加载插件路径: {extension_path}")
|
||||
|
||||
if not os.path.exists(extension_path):
|
||||
raise FileNotFoundError(
|
||||
f"插件不存在: {extension_path}\n请确保 turnstilePatch 文件夹在正确位置"
|
||||
)
|
||||
|
||||
return extension_path
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
# 加载配置
|
||||
config = load_config()
|
||||
|
||||
# 固定的 URL 配置
|
||||
login_url = "https://authenticator.cursor.sh"
|
||||
sign_up_url = "https://authenticator.cursor.sh/sign-up"
|
||||
settings_url = "https://www.cursor.com/settings"
|
||||
mail_url = "https://tempmail.plus"
|
||||
|
||||
# 账号信息
|
||||
account = config["account"]
|
||||
password = config["password"]
|
||||
first_name = config["first_name"]
|
||||
last_name = config["last_name"]
|
||||
|
||||
auto_update_cursor_auth = True
|
||||
|
||||
# 浏览器配置
|
||||
co = ChromiumOptions()
|
||||
try:
|
||||
extension_path = get_extension_path()
|
||||
co.add_extension(extension_path)
|
||||
except FileNotFoundError as e:
|
||||
print(f"警告: {e}")
|
||||
print("将尝试继续执行...")
|
||||
|
||||
co.headless() # 无头模式
|
||||
co.set_user_agent(
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36"
|
||||
)
|
||||
co.set_pref("credentials_enable_service", False)
|
||||
co.set_argument("--hide-crash-restore-bubble")
|
||||
co.auto_port()
|
||||
# co.set_argument('--no-sandbox') # 无沙盒模式 用于linux
|
||||
# co.set_argument('--headless=new') #无界面系统启动参数 用于linux
|
||||
# co.set_proxy('127.0.0.1:10809') #设置代理
|
||||
|
||||
browser = Chromium(co)
|
||||
tab = browser.latest_tab
|
||||
tab.run_js("try { turnstile.reset() } catch(e) { }")
|
||||
|
||||
print("开始执行删除和注册流程")
|
||||
print("***请确认已经用https://tempmail.plus/zh邮箱成功申请过cursor账号!***")
|
||||
tab.get(login_url)
|
||||
|
||||
# 执行删除和注册流程
|
||||
if delete_account(browser, tab):
|
||||
print("账户删除成功")
|
||||
time.sleep(3)
|
||||
if sign_up_account(browser, tab):
|
||||
token = get_cursor_session_token(tab)
|
||||
print(f"CursorSessionToken: {token}")
|
||||
print("账户注册成功")
|
||||
if auto_update_cursor_auth:
|
||||
update_cursor_auth(
|
||||
email=account, access_token=token, refresh_token=token
|
||||
)
|
||||
else:
|
||||
print("账户注册失败")
|
||||
else:
|
||||
print("账户删除失败")
|
||||
|
||||
print("脚本执行完毕")
|
||||
browser.quit()
|
||||
|
||||
# 添加等待用户输入后再退出
|
||||
input("\n按回车键退出...")
|
||||
except FileNotFoundError as e:
|
||||
print(f"<EFBFBD><EFBFBD><EFBFBD>误: {e}")
|
||||
print("请确保 config.ini 文件存在并包含正确的配置信息")
|
||||
input("\n按回车键退出...")
|
||||
except Exception as e:
|
||||
print(f"加载配置时出错: {e}")
|
||||
input("\n按回车键退出...")
|
||||
5
dist/config - 副本.ini
vendored
Normal file
5
dist/config - 副本.ini
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
[Account]
|
||||
email = xxxx
|
||||
password = xxx
|
||||
first_name = xxxx
|
||||
last_name = xxxx
|
||||
5
dist/config.ini
vendored
Normal file
5
dist/config.ini
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
[Account]
|
||||
email = apxeme@mailto.plus
|
||||
password = ccz14321@
|
||||
first_name = cheng
|
||||
last_name = zhen
|
||||
BIN
dist/cursor_pro_keep_alive.exe
vendored
Normal file
BIN
dist/cursor_pro_keep_alive.exe
vendored
Normal file
Binary file not shown.
95
dist/readme.md
vendored
Normal file
95
dist/readme.md
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
|
||||
# Cursor Pro Keep Alive 使用说明文档
|
||||
|
||||
## 1. 软件介绍
|
||||
Cursor Pro Keep Alive 是一个自动化工具,用于管理 Cursor 账号的注册和更新。该工具可以自动执行账号删除和重新注册流程,以保持账号活跃。
|
||||
|
||||
## 2. 安装和准备
|
||||
|
||||
### 2.1 必要文件
|
||||
确保您有以下文件:
|
||||
- `cursor_pro_keep_alive.exe` - 主程序
|
||||
- `config.ini` - 配置文件
|
||||
- `turnstilePatch` - 插件文件夹
|
||||
|
||||
### 2.2 文件结构
|
||||
```
|
||||
your_folder/
|
||||
├── cursor_pro_keep_alive.exe
|
||||
├── config.ini
|
||||
└── turnstilePatch/
|
||||
└── (插件文件)
|
||||
```
|
||||
|
||||
## 3. 配置文件设置
|
||||
|
||||
在运行程序前,需要正确配置 `config.ini` 文件:
|
||||
|
||||
```ini
|
||||
[Account]
|
||||
email = your_username@mailto.plus # 邮箱地址(必须使用 mailto.plus 域名)
|
||||
password = your_password # 账号密码
|
||||
first_name = your_firstname # 名字
|
||||
last_name = your_lastname # 姓氏
|
||||
```
|
||||
|
||||
注意事项:
|
||||
- 邮箱必须使用 `mailto.plus` 域名
|
||||
- 请确保配置文件使用 UTF-8 编码保存
|
||||
|
||||
## 4. 运行程序
|
||||
|
||||
### 4.1 运行步骤
|
||||
1. 确保所有必要文件都在同一目录下
|
||||
2. 双击运行 `cursor_pro_keep_alive.exe`
|
||||
3. 程序会自动执行以下操作:
|
||||
- 删除现有账号
|
||||
- 注册新账号
|
||||
- 更新认证信息
|
||||
|
||||
### 4.2 运行提示
|
||||
- 程序运行过程中会显示各个步骤的执行状态
|
||||
- 如果出现验证码,程序会自动处理
|
||||
- 运行完成后会显示操作结果
|
||||
|
||||
## 5. 常见问题解决
|
||||
|
||||
### 5.1 配置文件错误
|
||||
错误提示:`配置文件不存在`
|
||||
- 解决方法:确保 `config.ini` 文件在程序同目录下
|
||||
|
||||
### 5.2 插件加载失败
|
||||
错误提示:`插件不存在`
|
||||
- 解决方法:确保 `turnstilePatch` 文件夹在程序同目录下
|
||||
- 注意:即使插件加载失败,程序仍会继续执行
|
||||
|
||||
### 5.3 账号注册失败
|
||||
- 检查邮箱格式是否正确(必须是 mailto.plus)
|
||||
- 确保密码符合要求
|
||||
- 检查网络连接是否正常
|
||||
|
||||
## 6. 注意事项
|
||||
|
||||
1. 运行环境要求:
|
||||
- Windows 操作系统
|
||||
- 稳定的网络连接
|
||||
|
||||
2. 安全提示:
|
||||
- 请妥善保管配置文件,避免泄露账号信息
|
||||
- 建议定期更改密码
|
||||
|
||||
3. 使用建议:
|
||||
- 建议在非高峰时段运行程序
|
||||
- 保持配置文件的定期备份
|
||||
|
||||
## 7. 技术支持
|
||||
|
||||
如遇到问题,请检查:
|
||||
1. 配置文件格式是否正确
|
||||
2. 必要文件是否完整
|
||||
3. 网络连接是否正常
|
||||
|
||||
## 8. 免责声明
|
||||
|
||||
本程序仅供学习和研究使用,请遵守相关服务条款和法律法规。使用本程序产生的任何后果由用户自行承担。
|
||||
166
gpt-accesstoken.py
Normal file
166
gpt-accesstoken.py
Normal file
@@ -0,0 +1,166 @@
|
||||
from DrissionPage import ChromiumOptions, Chromium
|
||||
import random
|
||||
import time
|
||||
|
||||
def handle_turnstile(tab):
|
||||
"""处理 Turnstile 验证"""
|
||||
print("准备处理验证")
|
||||
try:
|
||||
while True:
|
||||
if tab.ele('@id=email-input', timeout=2):
|
||||
print("无需验证 - 邮箱输入框已加载")
|
||||
return True
|
||||
|
||||
if tab.ele('@id=password', timeout=2):
|
||||
print("无需验证 - 密码输入框已加载")
|
||||
return True
|
||||
|
||||
try:
|
||||
challenge_element = (tab.ele("@name=cf-turnstile-response", timeout=2)
|
||||
.parent()
|
||||
.shadow_root
|
||||
.ele("tag:iframe")
|
||||
.ele("tag:body")
|
||||
.sr("tag:input"))
|
||||
|
||||
if challenge_element:
|
||||
print("验证框加载完成")
|
||||
time.sleep(random.uniform(1, 3))
|
||||
challenge_element.click()
|
||||
print("验证按钮已点击,等待验证完成...")
|
||||
time.sleep(2)
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
except Exception as e:
|
||||
print(f"验证处理出错: {str(e)}")
|
||||
print('跳过验证')
|
||||
return False
|
||||
|
||||
account = 'your_chatgpt_account'
|
||||
password = 'your_chatgpt_password'
|
||||
|
||||
co = ChromiumOptions()
|
||||
co.add_extension("turnstilePatch")
|
||||
# co.headless()
|
||||
co.set_user_agent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.92 Safari/537.36')
|
||||
co.set_pref('credentials_enable_service', False)
|
||||
co.set_argument('--hide-crash-restore-bubble')
|
||||
co.auto_port()
|
||||
|
||||
browser = Chromium(co)
|
||||
tab = browser.latest_tab
|
||||
tab.run_js("try { turnstile.reset() } catch(e) { }")
|
||||
|
||||
print("\n步骤1: 开始访问网站...")
|
||||
|
||||
tab.get('https://chatgpt.com')
|
||||
print('等待页面加载...')
|
||||
|
||||
print("\n步骤2: 开始登录...")
|
||||
for _ in range(5):
|
||||
try:
|
||||
if tab.ele('xpath:/html/body/div[1]/div[1]/main/div[1]/div[1]/div/div[1]/div/div[3]/div/button[1]'):
|
||||
signin_btn = tab.ele('xpath:/html/body/div[1]/div[1]/main/div[1]/div[1]/div/div[1]/div/div[3]/div/button[1]')
|
||||
print("找到黑色登录按钮:", signin_btn.text)
|
||||
break
|
||||
if tab.ele('@data-testid=login-button'):
|
||||
signin_btn = tab.ele('@data-testid=login-button')
|
||||
print("找到蓝色登录按钮:", signin_btn.text)
|
||||
break
|
||||
if tab.ele("@name=cf-turnstile-response"):
|
||||
print('加载页面时出现CF验证, IP 质量太差, 请更换 IP 重新尝试!')
|
||||
browser.quit()
|
||||
exit()
|
||||
time.sleep(3)
|
||||
except Exception as e:
|
||||
print(f"处理登录按钮时出错: {str(e)}")
|
||||
|
||||
for _ in range(5):
|
||||
try:
|
||||
if signin_btn:
|
||||
signin_btn.click()
|
||||
print("点击登录按钮")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"处理登录按钮时出错: {str(e)}")
|
||||
time.sleep(3)
|
||||
else:
|
||||
print("尝试点击登录按钮失败,程序退出")
|
||||
exit()
|
||||
|
||||
handle_turnstile(tab)
|
||||
|
||||
print("\n步骤3: 输入邮箱...")
|
||||
for _ in range(5):
|
||||
try:
|
||||
if tab.ele('@id=email-input'):
|
||||
tab.actions.click('@id=email-input').type(account)
|
||||
time.sleep(0.5)
|
||||
tab.ele('@class=continue-btn').click()
|
||||
print("输入邮箱并点击继续")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"加载邮箱输入框时出错: {str(e)}")
|
||||
time.sleep(3)
|
||||
else:
|
||||
print("尝试加载邮箱输入框失败,程序退出")
|
||||
browser.quit()
|
||||
exit()
|
||||
|
||||
handle_turnstile(tab)
|
||||
|
||||
print("\n步骤4: 输入密码...")
|
||||
for _ in range(5):
|
||||
try:
|
||||
if tab.ele('@id=password'):
|
||||
print("密码输入框加载完成")
|
||||
tab.actions.click('@id=password').input(password)
|
||||
time.sleep(2)
|
||||
tab.ele('@type=submit').click('js')
|
||||
# tab.actions.click('@type=submit')
|
||||
print("输入密码并JS点击登录")
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"输入密码时出错: {str(e)}")
|
||||
time.sleep(3)
|
||||
else:
|
||||
print("尝试加载密码输入框失败,程序退出")
|
||||
browser.quit()
|
||||
exit()
|
||||
|
||||
for _ in range(5):
|
||||
try:
|
||||
if tab.ele('有什么可以帮忙的?'):
|
||||
print('登录成功!')
|
||||
break
|
||||
if tab.ele('重新发送电子邮件'):
|
||||
print('提示需要邮箱验证码,脚本终止,请手动获取')
|
||||
exit()
|
||||
except Exception as e:
|
||||
print(f"登录可能遇到问题: {str(e)}")
|
||||
time.sleep(3)
|
||||
else:
|
||||
print("登录失败,程序退出")
|
||||
browser.quit()
|
||||
exit()
|
||||
|
||||
time.sleep(random.uniform(1,2))
|
||||
print('\n',"步骤5: 获取access_token...")
|
||||
browser.new_tab('https://chatgpt.com/api/auth/session')
|
||||
tab = browser.latest_tab
|
||||
time.sleep(1)
|
||||
response_json = tab.json
|
||||
if response_json and 'accessToken' in response_json:
|
||||
access_token = response_json['accessToken']
|
||||
print('\n',"请复制保存你的access_token:",'\n')
|
||||
print(access_token)
|
||||
else:
|
||||
print("错误:未找到access token")
|
||||
|
||||
# input("\n按Enter键关闭浏览器...")
|
||||
browser.quit()
|
||||
|
||||
90
log.txt
Normal file
90
log.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
[2024/12/26 <20><><EFBFBD><EFBFBD> 13:11:03.37] 开始执行脚<E8A18C><E8849A>?
|
||||
[2024/12/26 <20><><EFBFBD><EFBFBD> 13:17:58.13] 开始执行脚<E8A18C><E8849A>?
|
||||
<EFBFBD><EFBFBD>ʼִ<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
***<2A><>ȷ<EFBFBD><C8B7><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>https://tempmail.plus/zh<7A><68><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cursor<6F>˺ţ<CBBA>***
|
||||
|
||||
<EFBFBD><EFBFBD>ʼɾ<EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺<EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Continue
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Sign in
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Adavance
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Delete Account
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>delete
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Delete
|
||||
<EFBFBD>˻<EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD>ʼע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD>...
|
||||
<EFBFBD>Ѵ<EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD>ᰴť
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Continue<EFBFBD><EFBFBD>ť
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD> Cursor <no-reply@cursor.sh>
|
||||
07:19
|
||||
Verify your email address
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD>룺 227917
|
||||
ɾ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>
|
||||
<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD> 227917
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>
|
||||
ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Cursor <20>˺ţ<CBBA> apxeme@mailto.plus
|
||||
<20><><EFBFBD>룺 ccz14321@
|
||||
CursorSessionToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhdXRoMHx1c2VyXzAxSkcwUEZXQUNHSEQ5SDVNU1RWWlFHUDZOIiwidGltZSI6IjE3MzUxOTA0MDEiLCJyYW5kb21uZXNzIjoiYTM4NDBhYzEtZGYwNi00NDhkIiwiZXhwIjo0MzI3MTkwNDAxLCJpc3MiOiJodHRwczovL2F1dGhlbnRpY2F0aW9uLmN1cnNvci5zaCIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJhdWQiOiJodHRwczovL2N1cnNvci5jb20ifQ.YYQ_C4BjbkHlShTFElkOvXFDqA8kYA-aWMqHKLa5RsU
|
||||
<EFBFBD>˻<EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD>
|
||||
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> cachedEmail
|
||||
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> accessToken
|
||||
<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> refreshToken
|
||||
<EFBFBD>ű<EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
[2024/12/26 <20><><EFBFBD><EFBFBD> 13:20:14.57] 脚本执行完成
|
||||
Traceback (most recent call last):
|
||||
File "cursor_pro_keep_alive.py", line 370, in <module>
|
||||
if delete_account(browser, tab):
|
||||
~~~~~~~~~~~~~~^^^^^^^^^^^^^^
|
||||
File "cursor_pro_keep_alive.py", line 146, in delete_account
|
||||
if tab.ele("Account Settings"):
|
||||
~~~~~~~^^^^^^^^^^^^^^^^^^^^
|
||||
File "DrissionPage\_pages\mix_tab.py", line 109, in ele
|
||||
File "DrissionPage\_pages\chromium_base.py", line 424, in ele
|
||||
File "DrissionPage\_base\base.py", line 356, in _ele
|
||||
File "DrissionPage\_pages\mix_tab.py", line 192, in _find_elements
|
||||
File "DrissionPage\_pages\chromium_base.py", line 492, in _find_elements
|
||||
File "DrissionPage\_base\driver.py", line 176, in run
|
||||
File "DrissionPage\_base\driver.py", line 84, in _send
|
||||
File "queue.py", line 213, in get
|
||||
File "threading.py", line 363, in wait
|
||||
KeyboardInterrupt
|
||||
[PYI-35588:ERROR] Failed to execute script 'cursor_pro_keep_alive' due to unhandled exception!
|
||||
<EFBFBD><EFBFBD>ʼִ<EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
***<2A><>ȷ<EFBFBD><C8B7><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>https://tempmail.plus/zh<7A><68><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>cursor<6F>˺ţ<CBBA>***
|
||||
|
||||
<EFBFBD><EFBFBD>ʼɾ<EFBFBD><EFBFBD><EFBFBD>˻<EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˺<EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Continue
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Sign in
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ť<EFBFBD>ѵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
||||
27
requirements.txt
Normal file
27
requirements.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
altgraph==0.17.4
|
||||
certifi==2024.12.14
|
||||
charset-normalizer==3.4.1
|
||||
click==8.1.8
|
||||
colorama==0.4.6
|
||||
cssselect==1.2.0
|
||||
DataRecorder==3.6.2
|
||||
DownloadKit==2.0.7
|
||||
DrissionPage==4.1.0.9
|
||||
et_xmlfile==2.0.0
|
||||
filelock==3.16.1
|
||||
idna==3.10
|
||||
lxml==5.3.0
|
||||
openpyxl==3.1.5
|
||||
packaging==24.2
|
||||
pefile==2023.2.7
|
||||
psutil==6.1.1
|
||||
pyinstaller==6.11.1
|
||||
pyinstaller-hooks-contrib==2024.11
|
||||
PyVirtualDisplay==3.0
|
||||
pywin32-ctypes==0.2.3
|
||||
requests==2.32.3
|
||||
requests-file==2.1.0
|
||||
setuptools==75.6.0
|
||||
tldextract==5.1.3
|
||||
urllib3==2.3.0
|
||||
websocket-client==1.8.0
|
||||
11
run_cursor.bat
Normal file
11
run_cursor.bat
Normal file
@@ -0,0 +1,11 @@
|
||||
@echo off
|
||||
:: 设置控制台代码页为 UTF-8
|
||||
chcp 65001
|
||||
:: 设置 Python 环境变量为 UTF-8
|
||||
set PYTHONIOENCODING=utf-8
|
||||
|
||||
echo [%date% %time%] 开始执行脚本 >> log.txt
|
||||
cd /d "%~dp0"
|
||||
python cursor_pro_keep_alive.py >> log.txt 2>&1
|
||||
echo [%date% %time%] 脚本执行完成 >> log.txt
|
||||
pause
|
||||
18
turnstilePatch/manifest.json
Normal file
18
turnstilePatch/manifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Turnstile Patcher",
|
||||
"version": "2.1",
|
||||
"content_scripts": [
|
||||
{
|
||||
"js": [
|
||||
"./script.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"run_at": "document_start",
|
||||
"all_frames": true,
|
||||
"world": "MAIN"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
turnstilePatch/readme.txt
Normal file
1
turnstilePatch/readme.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
12
turnstilePatch/script.js
Normal file
12
turnstilePatch/script.js
Normal file
@@ -0,0 +1,12 @@
|
||||
function getRandomInt(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
// old method wouldn't work on 4k screens
|
||||
|
||||
let screenX = getRandomInt(800, 1200);
|
||||
let screenY = getRandomInt(400, 600);
|
||||
|
||||
Object.defineProperty(MouseEvent.prototype, 'screenX', { value: screenX });
|
||||
|
||||
Object.defineProperty(MouseEvent.prototype, 'screenY', { value: screenY });
|
||||
46
update_cursor_auth.py
Normal file
46
update_cursor_auth.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from cursor_auth_manager import CursorAuthManager
|
||||
|
||||
def update_cursor_auth(email=None, access_token=None, refresh_token=None):
|
||||
"""
|
||||
更新Cursor的认证信息的便捷函数
|
||||
"""
|
||||
auth_manager = CursorAuthManager()
|
||||
return auth_manager.update_auth(email, access_token, refresh_token)
|
||||
|
||||
def main():
|
||||
# 示例用法
|
||||
print("请选择要更新的项目:")
|
||||
print("1. 更新邮箱")
|
||||
print("2. 更新访问令牌")
|
||||
print("3. 更新刷新令牌")
|
||||
print("4. 更新多个值")
|
||||
print("0. 退出")
|
||||
|
||||
choice = input("\n请输入选项数字: ")
|
||||
|
||||
if choice == "1":
|
||||
email = input("请输入新的邮箱: ")
|
||||
update_cursor_auth(email=email)
|
||||
elif choice == "2":
|
||||
token = input("请输入新的访问令牌: ")
|
||||
update_cursor_auth(access_token=token)
|
||||
elif choice == "3":
|
||||
token = input("请输入新的刷新令牌: ")
|
||||
update_cursor_auth(refresh_token=token)
|
||||
elif choice == "4":
|
||||
email = input("请输入新的邮箱 (直接回车跳过): ")
|
||||
access_token = input("请输入新的访问令牌 (直接回车跳过): ")
|
||||
refresh_token = input("请输入新的刷新令牌 (直接回车跳过): ")
|
||||
|
||||
update_cursor_auth(
|
||||
email=email if email else None,
|
||||
access_token=access_token if access_token else None,
|
||||
refresh_token=refresh_token if refresh_token else None
|
||||
)
|
||||
elif choice == "0":
|
||||
print("退出程序")
|
||||
else:
|
||||
print("无效的选项")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user