Add bypass token limit functionality

- Introduced a new script `bypass_token_limit.py` to modify the `workbench.desktop.main.js` file, allowing users to bypass token limits.
- Updated localization files to include new strings for the bypass token limit feature in English, Simplified Chinese, and Traditional Chinese.
- Enhanced CHANGELOG.md to reflect the addition of the bypass token limit feature and related fixes.
This commit is contained in:
yeongpin 2025-04-11 10:53:06 +08:00
parent 9f51ba8128
commit 4746af7ce9
5 changed files with 199 additions and 3 deletions

View File

@ -1,5 +1,9 @@
# Change Log # Change Log
## v1.8.11
1. Add: Bypass Token Limit | 添加繞過 Token 限制
2. Fix: Some Issues | 修復一些問題
## v1.8.10 ## v1.8.10
1. Add: Check User Authorized | 添加檢查用戶授權 1. Add: Check User Authorized | 添加檢查用戶授權
2. Fix: Linux Reset Process Error: 'base' | 修復 Linux 重置過程錯誤:'base' 2. Fix: Linux Reset Process Error: 'base' | 修復 Linux 重置過程錯誤:'base'

174
bypass_token_limit.py Normal file
View File

@ -0,0 +1,174 @@
import os
import shutil
import platform
import tempfile
import glob
from colorama import Fore, Style, init
import configparser
from new_signup import get_user_documents_path
from config import get_config
from datetime import datetime
# Initialize colorama
init()
# Define emoji constants
EMOJI = {
"FILE": "📄",
"BACKUP": "💾",
"SUCCESS": "",
"ERROR": "",
"INFO": "",
"RESET": "🔄",
"WARNING": "⚠️",
}
def get_workbench_cursor_path(translator=None) -> str:
"""Get Cursor workbench.desktop.main.js path"""
system = platform.system()
# Read configuration
config_dir = os.path.join(get_user_documents_path(), ".cursor-free-vip")
config_file = os.path.join(config_dir, "config.ini")
config = configparser.ConfigParser()
if os.path.exists(config_file):
config.read(config_file)
paths_map = {
"Darwin": { # macOS
"base": "/Applications/Cursor.app/Contents/Resources/app",
"main": "out/vs/workbench/workbench.desktop.main.js"
},
"Windows": {
"main": "out\\vs\\workbench\\workbench.desktop.main.js"
},
"Linux": {
"bases": ["/opt/Cursor/resources/app", "/usr/share/cursor/resources/app", "/usr/lib/cursor/app/"],
"main": "out/vs/workbench/workbench.desktop.main.js"
}
}
if system == "Linux":
# Add extracted AppImage with correct usr structure
extracted_usr_paths = glob.glob(os.path.expanduser("~/squashfs-root/usr/share/cursor/resources/app"))
paths_map["Linux"]["bases"].extend(extracted_usr_paths)
if system not in paths_map:
raise OSError(translator.get('reset.unsupported_os', system=system) if translator else f"不支持的操作系统: {system}")
if system == "Linux":
for base in paths_map["Linux"]["bases"]:
main_path = os.path.join(base, paths_map["Linux"]["main"])
print(f"{Fore.CYAN}{EMOJI['INFO']} Checking path: {main_path}{Style.RESET_ALL}")
if os.path.exists(main_path):
return main_path
if system == "Windows":
base_path = config.get('WindowsPaths', 'cursor_path')
elif system == "Darwin":
base_path = paths_map[system]["base"]
else: # Linux
# For Linux, we've already checked all bases in the loop above
# If we're here, it means none of the bases worked, so we'll use the first one
base_path = paths_map[system]["bases"][0]
main_path = os.path.join(base_path, paths_map[system]["main"])
if not os.path.exists(main_path):
raise OSError(translator.get('reset.file_not_found', path=main_path) if translator else f"未找到 Cursor main.js 文件: {main_path}")
return main_path
def modify_workbench_js(file_path: str, translator=None) -> bool:
"""
Modify file content
"""
try:
# Save original file permissions
original_stat = os.stat(file_path)
original_mode = original_stat.st_mode
original_uid = original_stat.st_uid
original_gid = original_stat.st_gid
# Create temporary file
with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", errors="ignore", delete=False) as tmp_file:
# Read original content
with open(file_path, "r", encoding="utf-8", errors="ignore") as main_file:
content = main_file.read()
patterns = {
# 通用按钮替换模式
r'B(k,D(Ln,{title:"Upgrade to Pro",size:"small",get codicon(){return A.rocket},get onClick(){return t.pay}}),null)': r'B(k,D(Ln,{title:"yeongpin GitHub",size:"small",get codicon(){return A.github},get onClick(){return function(){window.open("https://github.com/yeongpin/cursor-free-vip","_blank")}}}),null)',
# Windows/Linux/Mac 通用按钮替换模式
r'M(x,I(as,{title:"Upgrade to Pro",size:"small",get codicon(){return $.rocket},get onClick(){return t.pay}}),null)': r'M(x,I(as,{title:"yeongpin GitHub",size:"small",get codicon(){return $.rocket},get onClick(){return function(){window.open("https://github.com/yeongpin/cursor-free-vip","_blank")}}}),null)',
# Badge 替换
r'<div>Pro Trial': r'<div>Pro',
r'py-1">Auto-select': r'py-1">Bypass-Version-Pin',
#
r'async getEffectiveTokenLimit(e){const n=e.modelName;if(!n)return 2e5;':r'async getEffectiveTokenLimit(e){return 9000000;const n=e.modelName;if(!n)return 9e5;',
# Pro
r'var DWr=ne("<div class=settings__item_description>You are currently signed in with <strong></strong>.");': r'var DWr=ne("<div class=settings__item_description>You are currently signed in with <strong></strong>. <h1>Pro</h1>");',
# Toast 替换
r'notifications-toasts': r'notifications-toasts hidden'
}
# 使用patterns进行替换
for old_pattern, new_pattern in patterns.items():
content = content.replace(old_pattern, new_pattern)
# Write to temporary file
tmp_file.write(content)
tmp_path = tmp_file.name
# Backup original file with timestamp
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
backup_path = f"{file_path}.backup.{timestamp}"
shutil.copy2(file_path, backup_path)
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.backup_created', path=backup_path)}{Style.RESET_ALL}")
# Move temporary file to original position
if os.path.exists(file_path):
os.remove(file_path)
shutil.move(tmp_path, file_path)
# Restore original permissions
os.chmod(file_path, original_mode)
if os.name != "nt": # Not Windows
os.chown(file_path, original_uid, original_gid)
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.file_modified')}{Style.RESET_ALL}")
return True
except Exception as e:
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.modify_file_failed', error=str(e))}{Style.RESET_ALL}")
if "tmp_path" in locals():
try:
os.unlink(tmp_path)
except:
pass
return False
def run(translator=None):
config = get_config(translator)
if not config:
return False
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
print(f"{Fore.CYAN}{EMOJI['RESET']} {translator.get('bypass_token_limit.title')}{Style.RESET_ALL}")
print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
modify_workbench_js(get_workbench_cursor_path(translator), translator)
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
input(f"{EMOJI['INFO']} {translator.get('bypass_token_limit.press_enter')}...")
if __name__ == "__main__":
from main import translator as main_translator
run(main_translator)

View File

@ -31,7 +31,8 @@
"operation_cancelled_by_user": "Operation cancelled by user", "operation_cancelled_by_user": "Operation cancelled by user",
"exiting": "Exiting ……", "exiting": "Exiting ……",
"bypass_version_check": "Bypass Cursor Version Check", "bypass_version_check": "Bypass Cursor Version Check",
"check_user_authorized": "Check User Authorized" "check_user_authorized": "Check User Authorized",
"bypass_token_limit": "Bypass Token Limit"
}, },
"languages": { "languages": {
"en": "English", "en": "English",
@ -727,5 +728,10 @@
"checking_usage_information": "Checking usage information...", "checking_usage_information": "Checking usage information...",
"check_usage_response": "Check usage response: {response}", "check_usage_response": "Check usage response: {response}",
"usage_response": "Usage response: {response}" "usage_response": "Usage response: {response}"
},
"bypass_token_limit": {
"title": "Bypass Token Limit Tool",
"description": "This tool modifies the workbench.desktop.main.js file to bypass the token limit",
"press_enter": "Press Enter to continue..."
} }
} }

View File

@ -31,7 +31,8 @@
"operation_cancelled_by_user": "操作被用户取消", "operation_cancelled_by_user": "操作被用户取消",
"exiting": "退出中 ……", "exiting": "退出中 ……",
"bypass_version_check": "绕过 Cursor 版本检查", "bypass_version_check": "绕过 Cursor 版本检查",
"check_user_authorized": "检查用户授权" "check_user_authorized": "检查用户授权",
"bypass_token_limit": "绕过 Token 限制"
}, },
"languages": { "languages": {
"en": "英语", "en": "英语",
@ -705,5 +706,10 @@
"checking_usage_information": "检查使用情况...", "checking_usage_information": "检查使用情况...",
"check_usage_response": "检查使用情况响应: {response}", "check_usage_response": "检查使用情况响应: {response}",
"usage_response": "使用情况响应: {response}" "usage_response": "使用情况响应: {response}"
},
"bypass_token_limit": {
"title": "绕过 Token 限制工具",
"description": "此工具修改 workbench.desktop.main.js 文件以绕过 token 限制",
"press_enter": "按回车键继续..."
} }
} }

View File

@ -31,7 +31,8 @@
"operation_cancelled_by_user": "操作被使用者取消", "operation_cancelled_by_user": "操作被使用者取消",
"exiting": "退出中 ……", "exiting": "退出中 ……",
"bypass_version_check": "繞過 Cursor 版本檢查", "bypass_version_check": "繞過 Cursor 版本檢查",
"check_user_authorized": "檢查用戶授權" "check_user_authorized": "檢查用戶授權",
"bypass_token_limit": "繞過 Token 限制"
}, },
"languages": { "languages": {
"en": "英文", "en": "英文",
@ -687,5 +688,10 @@
"checking_usage_information": "檢查使用情況...", "checking_usage_information": "檢查使用情況...",
"check_usage_response": "檢查使用情況響應: {response}", "check_usage_response": "檢查使用情況響應: {response}",
"usage_response": "使用情況響應: {response}" "usage_response": "使用情況響應: {response}"
},
"bypass_token_limit": {
"title": "繞過 Token 限制工具",
"description": "此工具修改 workbench.desktop.main.js 文件以繞過 token 限制",
"press_enter": "按回車鍵繼續..."
} }
} }