diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3cf8996..5442dc4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -228,10 +228,30 @@ jobs: echo "Contents of subdirectories:" ls -la */ + - name: Extract changelog for current version + id: get_changelog + run: | + # Extract changelog for current version + CHANGELOG_CONTENT=$(awk -v ver="v${{ env.VERSION }}" ' + BEGIN { found=0; content=""; } + /^## v[0-9]+\.[0-9]+\.[0-9]+/ { + if (found == 1) { exit } + if ($0 ~ ver) { found=1; next } + } + found == 1 { content = content $0 "\n" } + END { print content } + ' CHANGELOG.md) + + # Save changelog content to environment variable + echo 'CHANGELOG_CONTENT<> $GITHUB_ENV + echo "$CHANGELOG_CONTENT" >> $GITHUB_ENV + echo 'EOF' >> $GITHUB_ENV + - name: Create Release uses: softprops/action-gh-release@v1 with: tag_name: v${{ env.VERSION }} + name: Release v${{ env.VERSION }} files: | artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64 @@ -240,5 +260,9 @@ jobs: artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP_${{ env.VERSION }}_mac_intel draft: false prerelease: false + body: | + # Release v${{ env.VERSION }} + + ${{ env.CHANGELOG_CONTENT }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 9441fb3..85f11fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v1.8.09 1. Add: Force Update Config | 添加強制更新配置 2. Add: Multilanguage support for force update | 添加強制更新功能的多語言支持 +3. Fix: Reset break | 修復重置中斷 3. Fix: Some Issues | 修復一些問題 ## v1.8.08 diff --git a/reset_machine_manual.py b/reset_machine_manual.py index 78629c6..f4cb01b 100644 --- a/reset_machine_manual.py +++ b/reset_machine_manual.py @@ -15,6 +15,7 @@ import configparser from new_signup import get_user_documents_path import traceback from config import get_config +from datetime import datetime # Initialize colorama init() @@ -334,37 +335,40 @@ def modify_workbench_js(file_path: str, translator=None) -> bool: with open(file_path, "r", encoding="utf-8", errors="ignore") as main_file: content = main_file.read() - if sys.platform == "win32": - # Define replacement patterns - CButton_old_pattern = r'M(x,I(as,{title:"Upgrade to Pro",size:"small",get codicon(){return $.rocket},get onClick(){return t.pay}}),null)' - CButton_new_pattern = 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)' - elif sys.platform == "linux": - CButton_old_pattern = r'M(x,I(as,{title:"Upgrade to Pro",size:"small",get codicon(){return $.rocket},get onClick(){return t.pay}}),null)' - CButton_new_pattern = 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)' - elif sys.platform == "darwin": - CButton_old_pattern = r'M(x,I(as,{title:"Upgrade to Pro",size:"small",get codicon(){return $.rocket},get onClick(){return t.pay}}),null)' - CButton_new_pattern = 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)' + 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', - CBadge_old_pattern = r'
Pro Trial' - CBadge_new_pattern = 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' + } - CToast_old_pattern = r'notifications-toasts' - CToast_new_pattern = r'notifications-toasts hidden' - - # Replace content - content = content.replace(CButton_old_pattern, CButton_new_pattern) - content = content.replace(CBadge_old_pattern, CBadge_new_pattern) - content = content.replace(CToast_old_pattern, CToast_new_pattern) + # 使用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 - backup_path = file_path + ".backup" - if os.path.exists(backup_path): - os.remove(backup_path) + # 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): @@ -411,7 +415,10 @@ def modify_main_js(main_path: str, translator) -> bool: tmp_file.write(content) tmp_path = tmp_file.name - shutil.copy2(main_path, main_path + ".old") + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + backup_path = f"{main_path}.old.{timestamp}" + shutil.copy2(main_path, backup_path) + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.backup_created', path=backup_path)}{Style.RESET_ALL}") shutil.move(tmp_path, main_path) os.chmod(main_path, original_mode) @@ -461,7 +468,8 @@ def patch_cursor_get_machine_id(translator) -> bool: print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('reset.version_check_passed')}{Style.RESET_ALL}") # Backup file - backup_path = main_path + ".bak" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + backup_path = f"{main_path}.bak.{timestamp}" if not os.path.exists(backup_path): shutil.copy2(main_path, backup_path) print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.backup_created', path=backup_path)}{Style.RESET_ALL}") @@ -638,8 +646,8 @@ class MachineIDResetter: winreg.SetValueEx(key, "MachineGuid", 0, winreg.REG_SZ, new_guid) winreg.CloseKey(key) print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('reset.windows_machine_guid_updated')}{Style.RESET_ALL}") - except PermissionError: - print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('reset.permission_denied')}{Style.RESET_ALL}") + except PermissionError as e: + print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('reset.permission_denied', error=str(e))}{Style.RESET_ALL}") raise except Exception as e: print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('reset.update_windows_machine_guid_failed', error=str(e))}{Style.RESET_ALL}") @@ -717,12 +725,10 @@ class MachineIDResetter: with open(self.db_path, "r", encoding="utf-8") as f: config = json.load(f) - backup_path = self.db_path + ".bak" - if not os.path.exists(backup_path): - print(f"{Fore.YELLOW}{EMOJI['BACKUP']} {self.translator.get('reset.creating_backup')}: {backup_path}{Style.RESET_ALL}") - shutil.copy2(self.db_path, backup_path) - else: - print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('reset.backup_exists')}{Style.RESET_ALL}") + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + backup_path = f"{self.db_path}.bak.{timestamp}" + print(f"{Fore.YELLOW}{EMOJI['BACKUP']} {self.translator.get('reset.creating_backup')}: {backup_path}{Style.RESET_ALL}") + shutil.copy2(self.db_path, backup_path) print(f"{Fore.CYAN}{EMOJI['RESET']} {self.translator.get('reset.generating')}...{Style.RESET_ALL}") new_ids = self.generate_new_ids() @@ -786,7 +792,8 @@ class MachineIDResetter: # Create backup if file exists if os.path.exists(machine_id_path): - backup_path = machine_id_path + ".backup" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + backup_path = f"{machine_id_path}.backup.{timestamp}" try: shutil.copy2(machine_id_path, backup_path) print(f"{Fore.GREEN}{EMOJI['INFO']} {self.translator.get('reset.backup_created', path=backup_path) if self.translator else f'Backup created at: {backup_path}'}{Style.RESET_ALL}")