diff --git a/CHANGELOG.md b/CHANGELOG.md index c440a2a..1318777 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## v1.8.11 +1. Add: Bypass Token Limit | 添加繞過 Token 限制 +2. Fix: Some Issues | 修復一些問題 + ## v1.8.10 1. Add: Check User Authorized | 添加檢查用戶授權 2. Fix: Linux Reset Process Error: 'base' | 修復 Linux 重置過程錯誤:'base' diff --git a/bypass_token_limit.py b/bypass_token_limit.py new file mode 100644 index 0000000..5f1a39b --- /dev/null +++ b/bypass_token_limit.py @@ -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'
Pro Trial': r'
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("
You are currently signed in with .");': r'var DWr=ne("
You are currently signed in with .

Pro

");', + + # 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) \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index 79ce939..da3bb7d 100644 --- a/locales/en.json +++ b/locales/en.json @@ -31,7 +31,8 @@ "operation_cancelled_by_user": "Operation cancelled by user", "exiting": "Exiting ……", "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": { "en": "English", @@ -727,5 +728,10 @@ "checking_usage_information": "Checking usage information...", "check_usage_response": "Check 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..." } } \ No newline at end of file diff --git a/locales/zh_cn.json b/locales/zh_cn.json index 2e6e520..4767999 100644 --- a/locales/zh_cn.json +++ b/locales/zh_cn.json @@ -31,7 +31,8 @@ "operation_cancelled_by_user": "操作被用户取消", "exiting": "退出中 ……", "bypass_version_check": "绕过 Cursor 版本检查", - "check_user_authorized": "检查用户授权" + "check_user_authorized": "检查用户授权", + "bypass_token_limit": "绕过 Token 限制" }, "languages": { "en": "英语", @@ -705,5 +706,10 @@ "checking_usage_information": "检查使用情况...", "check_usage_response": "检查使用情况响应: {response}", "usage_response": "使用情况响应: {response}" + }, + "bypass_token_limit": { + "title": "绕过 Token 限制工具", + "description": "此工具修改 workbench.desktop.main.js 文件以绕过 token 限制", + "press_enter": "按回车键继续..." } } \ No newline at end of file diff --git a/locales/zh_tw.json b/locales/zh_tw.json index 5e7c608..2a25c3e 100644 --- a/locales/zh_tw.json +++ b/locales/zh_tw.json @@ -31,7 +31,8 @@ "operation_cancelled_by_user": "操作被使用者取消", "exiting": "退出中 ……", "bypass_version_check": "繞過 Cursor 版本檢查", - "check_user_authorized": "檢查用戶授權" + "check_user_authorized": "檢查用戶授權", + "bypass_token_limit": "繞過 Token 限制" }, "languages": { "en": "英文", @@ -687,5 +688,10 @@ "checking_usage_information": "檢查使用情況...", "check_usage_response": "檢查使用情況響應: {response}", "usage_response": "使用情況響應: {response}" + }, + "bypass_token_limit": { + "title": "繞過 Token 限制工具", + "description": "此工具修改 workbench.desktop.main.js 文件以繞過 token 限制", + "press_enter": "按回車鍵繼續..." } } \ No newline at end of file