Last active
March 10, 2025 02:11
-
-
Save sadegh19b/d6d880320f643d93a318b15501882902 to your computer and use it in GitHub Desktop.
Cursor Trial Reset Tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
import json | |
import uuid | |
import hashlib | |
import shutil | |
import sqlite3 | |
import logging | |
from colorama import Fore, Style, init | |
# Set up logging | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(levelname)s - %(message)s', | |
handlers=[ | |
logging.StreamHandler(), | |
logging.FileHandler('reset_machine.log', encoding='utf-8') | |
] | |
) | |
logger = logging.getLogger(__name__) | |
# Initialize colorama | |
init() | |
# Define emoji constants | |
EMOJI = { | |
"FILE": "📄", | |
"BACKUP": "💾", | |
"SUCCESS": "✅", | |
"ERROR": "❌", | |
"INFO": "ℹ️", | |
"RESET": "🔄", | |
} | |
class MachineIDResetter: | |
def __init__(self): | |
# Determine the operating system | |
if sys.platform == "win32": # Windows | |
appdata = os.getenv("APPDATA") | |
if appdata is None: | |
raise EnvironmentError("APPDATA Environment Variable Not Set") | |
self.db_path = os.path.join( | |
appdata, "Cursor", "User", "globalStorage", "storage.json" | |
) | |
self.sqlite_path = os.path.join( | |
appdata, "Cursor", "User", "globalStorage", "state.vscdb" | |
) | |
elif sys.platform == "darwin": # macOS | |
self.db_path = os.path.abspath(os.path.expanduser( | |
"~/Library/Application Support/Cursor/User/globalStorage/storage.json" | |
)) | |
self.sqlite_path = os.path.abspath(os.path.expanduser( | |
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb" | |
)) | |
elif sys.platform == "linux": # Linux | |
self.db_path = os.path.abspath(os.path.expanduser( | |
"~/.config/Cursor/User/globalStorage/storage.json" | |
)) | |
self.sqlite_path = os.path.abspath(os.path.expanduser( | |
"~/.config/Cursor/User/globalStorage/state.vscdb" | |
)) | |
else: | |
raise NotImplementedError(f"Not Supported OS: {sys.platform}") | |
def generate_new_ids(self): | |
"""Generate new machine IDs""" | |
# Generate new UUID | |
dev_device_id = str(uuid.uuid4()) | |
# Generate new machineId (64-character hexadecimal) | |
machine_id = hashlib.sha256(os.urandom(32)).hexdigest() | |
# Generate new macMachineId (128-character hexadecimal) | |
mac_machine_id = hashlib.sha512(os.urandom(64)).hexdigest() | |
# Generate new sqmId | |
sqm_id = "{" + str(uuid.uuid4()).upper() + "}" | |
return { | |
"telemetry.devDeviceId": dev_device_id, | |
"telemetry.macMachineId": mac_machine_id, | |
"telemetry.machineId": machine_id, | |
"telemetry.sqmId": sqm_id, | |
"storage.serviceMachineId": dev_device_id, # Add storage.serviceMachineId | |
} | |
def update_sqlite_db(self, new_ids): | |
"""Update machine IDs in the SQLite database""" | |
try: | |
print(f"{Fore.CYAN}{EMOJI['INFO']} Updating SQLite database...{Style.RESET_ALL}") | |
conn = sqlite3.connect(self.sqlite_path) | |
cursor = conn.cursor() | |
cursor.execute(""" | |
CREATE TABLE IF NOT EXISTS ItemTable ( | |
key TEXT PRIMARY KEY, | |
value TEXT | |
) | |
""") | |
updates = [ | |
(key, value) for key, value in new_ids.items() | |
] | |
for key, value in updates: | |
cursor.execute(""" | |
INSERT OR REPLACE INTO ItemTable (key, value) | |
VALUES (?, ?) | |
""", (key, value)) | |
print(f"{EMOJI['INFO']} {Fore.CYAN} Updating pair: {key}{Style.RESET_ALL}") | |
conn.commit() | |
conn.close() | |
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} SQLite database updated successfully{Style.RESET_ALL}") | |
return True | |
except Exception as e: | |
print(f"{Fore.RED}{EMOJI['ERROR']} Error updating SQLite database: {str(e)}{Style.RESET_ALL}") | |
return False | |
def update_system_ids(self, new_ids): | |
"""Update system-level IDs""" | |
try: | |
print(f"{Fore.CYAN}{EMOJI['INFO']} Updating system IDs...{Style.RESET_ALL}") | |
if sys.platform.startswith("win"): | |
self._update_windows_machine_guid() | |
elif sys.platform == "darwin": | |
self._update_macos_platform_uuid(new_ids) | |
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} System IDs updated successfully{Style.RESET_ALL}") | |
return True | |
except Exception as e: | |
print(f"{Fore.RED}{EMOJI['ERROR']} System IDs update failed: {str(e)}{Style.RESET_ALL}") | |
logger.error(f"System IDs update failed: {e}") | |
return False | |
def _update_windows_machine_guid(self): | |
"""Update Windows MachineGuid""" | |
try: | |
import winreg | |
key = winreg.OpenKey( | |
winreg.HKEY_LOCAL_MACHINE, | |
"SOFTWARE\\Microsoft\\Cryptography", | |
0, | |
winreg.KEY_WRITE | winreg.KEY_WOW64_64KEY | |
) | |
new_guid = str(uuid.uuid4()) | |
winreg.SetValueEx(key, "MachineGuid", 0, winreg.REG_SZ, new_guid) | |
winreg.CloseKey(key) | |
logger.info("Windows MachineGuid updated successfully") | |
except PermissionError: | |
logger.error("Permission denied: Run as administrator to update Windows MachineGuid") | |
raise | |
except Exception as e: | |
logger.error(f"Failed to update Windows MachineGuid: {e}") | |
raise | |
def _update_macos_platform_uuid(self, new_ids): | |
"""Update macOS Platform UUID""" | |
try: | |
uuid_file = "/var/root/Library/Preferences/SystemConfiguration/com.apple.platform.uuid.plist" | |
if os.path.exists(uuid_file): | |
# Use sudo to execute the plutil command | |
cmd = f'sudo plutil -replace "UUID" -string "{new_ids["telemetry.macMachineId"]}" "{uuid_file}"' | |
result = os.system(cmd) | |
if result == 0: | |
logger.info("macOS Platform UUID updated successfully") | |
else: | |
raise Exception("Failed to execute plutil command") | |
except Exception as e: | |
logger.error(f"Failed to update macOS Platform UUID: {e}") | |
raise | |
def reset_machine_ids(self): | |
"""Reset machine IDs and back up the original files""" | |
try: | |
print(f"{Fore.CYAN}{EMOJI['INFO']} Checking...{Style.RESET_ALL}") | |
if not os.path.exists(self.db_path): | |
print(f"{Fore.RED}{EMOJI['ERROR']} File not found: {self.db_path}{Style.RESET_ALL}") | |
return False | |
if not os.access(self.db_path, os.R_OK | os.W_OK): | |
print(f"{Fore.RED}{EMOJI['ERROR']} No permission to access file.{Style.RESET_ALL}") | |
return False | |
print(f"{Fore.CYAN}{EMOJI['FILE']} Reading...{Style.RESET_ALL}") | |
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']} Creating backup: {backup_path}{Style.RESET_ALL}") | |
shutil.copy2(self.db_path, backup_path) | |
else: | |
print(f"{Fore.YELLOW}{EMOJI['INFO']} Backup file already exists.{Style.RESET_ALL}") | |
print(f"{Fore.CYAN}{EMOJI['RESET']} Generating new IDs...{Style.RESET_ALL}") | |
new_ids = self.generate_new_ids() | |
# Update the configuration file | |
config.update(new_ids) | |
print(f"{Fore.CYAN}{EMOJI['FILE']} Saving JSON...{Style.RESET_ALL}") | |
with open(self.db_path, "w", encoding="utf-8") as f: | |
json.dump(config, f, indent=4) | |
# Update the SQLite database | |
self.update_sqlite_db(new_ids) | |
# Update system IDs | |
self.update_system_ids(new_ids) | |
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Machine IDs reset successfully!{Style.RESET_ALL}") | |
print(f"\n{Fore.CYAN}New IDs:{Style.RESET_ALL}") | |
for key, value in new_ids.items(): | |
print(f"{EMOJI['INFO']} {key}: {Fore.GREEN}{value}{Style.RESET_ALL}") | |
return True | |
except PermissionError as e: | |
print(f"{Fore.RED}{EMOJI['ERROR']} Permission error: {str(e)}{Style.RESET_ALL}") | |
print(f"{Fore.YELLOW}{EMOJI['INFO']} Please run this script as administrator.{Style.RESET_ALL}") | |
return False | |
except Exception as e: | |
print(f"{Fore.RED}{EMOJI['ERROR']} An error occurred: {str(e)}{Style.RESET_ALL}") | |
return False | |
def run(): | |
"""Convenience function to directly call the reset functionality""" | |
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") | |
print(f"{Fore.CYAN}{EMOJI['RESET']} Cursor Machine ID Resetter{Style.RESET_ALL}") | |
print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}") | |
resetter = MachineIDResetter() | |
resetter.reset_machine_ids() | |
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") | |
input(f"{EMOJI['INFO']} Press Enter to exit...") | |
if __name__ == "__main__": | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment