备份: 完整开发状态(含反混淆脚本和临时文件)

This commit is contained in:
ccdojox-crypto
2025-12-17 17:18:02 +08:00
parent 9e2333c90c
commit 7e9ea173a7
2872 changed files with 326818 additions and 249 deletions

View File

@@ -0,0 +1,258 @@
'use strict';
// ============================================
// CursorPro API Client - 反混淆版本
// ============================================
Object.defineProperty(exports, "__esModule", { value: true });
const vscode = require('vscode');
// 默认 API 地址
const DEFAULT_API_URL = 'https://api.aicode.edu.pl';
const REQUEST_TIMEOUT = 15000; // 15秒超时
let isOnline = true;
let onlineStatusCallbacks = [];
/**
* 获取 API URL (从配置或使用默认值)
*/
function getApiUrl() {
const config = vscode.workspace.getConfiguration('cursorpro');
return config.get('apiUrl') || DEFAULT_API_URL;
}
exports.getApiUrl = getApiUrl;
/**
* 获取在线状态
*/
function getOnlineStatus() {
return isOnline;
}
exports.getOnlineStatus = getOnlineStatus;
/**
* 监听在线状态变化
*/
function onOnlineStatusChange(callback) {
onlineStatusCallbacks.push(callback);
return () => {
onlineStatusCallbacks = onlineStatusCallbacks.filter(cb => cb !== callback);
};
}
exports.onOnlineStatusChange = onOnlineStatusChange;
/**
* 设置在线状态
*/
function setOnlineStatus(status) {
if (isOnline !== status) {
isOnline = status;
onlineStatusCallbacks.forEach(callback => callback(status));
}
}
/**
* 带超时的 fetch
*/
async function fetchWithTimeout(url, options, timeout) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
clearTimeout(timeoutId);
throw error;
}
}
/**
* 通用请求函数
*/
async function request(endpoint, method = 'GET', body) {
const url = `${getApiUrl()}${endpoint}`;
const options = {
method: method,
headers: {
'Content-Type': 'application/json'
}
};
if (body) {
options.body = JSON.stringify(body);
}
try {
const response = await fetchWithTimeout(url, options, REQUEST_TIMEOUT);
const data = await response.json();
setOnlineStatus(true);
if (!response.ok && data.error) {
data.success = false;
data.message = data.error;
}
return data;
} catch (error) {
// 检查是否是网络错误
const isNetworkError = error.name === 'AbortError' ||
error.name === 'TypeError' ||
error.message?.includes('fetch') ||
error.message?.includes('network') ||
error.message?.includes('ECONNREFUSED') ||
error.message?.includes('ENOTFOUND') ||
error.message?.includes('ETIMEDOUT');
if (isNetworkError) {
setOnlineStatus(false);
return {
success: false,
error: '网络连接失败,请检查网络',
isOffline: true
};
}
throw error;
}
}
/**
* 验证 Key
*/
async function verifyKey(key) {
return request('/api/verify-key', 'POST', { key });
}
exports.verifyKey = verifyKey;
/**
* 切换账号
*/
async function switchAccount(key) {
return request('/api/switch-account', 'POST', { key });
}
exports.switchAccount = switchAccount;
/**
* 获取代理配置
*/
async function getProxyConfig() {
return request('/api/proxy-config', 'GET');
}
exports.getProxyConfig = getProxyConfig;
/**
* 更新代理配置
*/
async function updateProxyConfig(isEnabled, proxyUrl) {
return request('/api/proxy-config', 'PUT', {
is_enabled: isEnabled,
proxy_url: proxyUrl
});
}
exports.updateProxyConfig = updateProxyConfig;
// ============================================
// 无感换号 (Seamless Mode) API
// ============================================
/**
* 获取无缝模式状态
*/
async function getSeamlessStatus() {
return request('/api/seamless/status');
}
exports.getSeamlessStatus = getSeamlessStatus;
/**
* 获取用户切换状态
*/
async function getUserSwitchStatus(userKey) {
return request('/api/seamless/user-status?userKey=' + encodeURIComponent(userKey));
}
exports.getUserSwitchStatus = getUserSwitchStatus;
/**
* 获取无缝配置
*/
async function getSeamlessConfig() {
return request('/api/seamless/config');
}
exports.getSeamlessConfig = getSeamlessConfig;
/**
* 更新无缝配置
*/
async function updateSeamlessConfig(config) {
return request('/api/seamless/config', 'POST', config);
}
exports.updateSeamlessConfig = updateSeamlessConfig;
/**
* 注入无缝模式
*/
async function injectSeamless(apiUrl, userKey) {
return request('/api/seamless/inject', 'POST', {
api_url: apiUrl,
user_key: userKey
});
}
exports.injectSeamless = injectSeamless;
/**
* 恢复无缝模式
*/
async function restoreSeamless() {
return request('/api/seamless/restore', 'POST');
}
exports.restoreSeamless = restoreSeamless;
/**
* 获取无缝账号列表
*/
async function getSeamlessAccounts() {
return request('/api/seamless/accounts');
}
exports.getSeamlessAccounts = getSeamlessAccounts;
/**
* 同步无缝账号
*/
async function syncSeamlessAccounts(accounts) {
return request('/api/seamless/sync-accounts', 'POST', { accounts });
}
exports.syncSeamlessAccounts = syncSeamlessAccounts;
/**
* 获取无缝 Token
*/
async function getSeamlessToken(userKey) {
return request('/api/seamless/get-token?userKey=' + encodeURIComponent(userKey));
}
exports.getSeamlessToken = getSeamlessToken;
/**
* 切换无缝 Token
*/
async function switchSeamlessToken(userKey) {
return request('/api/seamless/switch-token', 'POST', {
mode: 'manual',
userKey: userKey
});
}
exports.switchSeamlessToken = switchSeamlessToken;
/**
* 获取最新版本
*/
async function getLatestVersion() {
return request('/api/version');
}
exports.getLatestVersion = getLatestVersion;

View File

@@ -0,0 +1,221 @@
'use strict';
// ============================================
// CursorPro Extension - 反混淆版本
// ============================================
Object.defineProperty(exports, "__esModule", { value: true });
const vscode = require('vscode');
const provider_1 = require('./webview/provider');
const fs = require('fs');
const path = require('path');
let usageStatusBarItem;
// 创建输出通道
exports.outputChannel = vscode.window.createOutputChannel('CursorPro');
/**
* 日志函数
*/
function log(message) {
const timestamp = new Date().toLocaleTimeString();
exports.outputChannel.appendLine('[' + timestamp + '] ' + message);
console.log('[CursorPro] ' + message);
}
exports.log = log;
/**
* 清理 Service Worker 缓存
*/
function cleanServiceWorkerCache() {
try {
const platform = process.platform;
const cachePaths = [];
if (platform === 'win32') {
const appData = process.env.APPDATA || '';
const localAppData = process.env.LOCALAPPDATA || '';
cachePaths.push(
path.join(appData, 'Cursor', 'Service Worker'),
path.join(localAppData, 'Cursor', 'Service Worker'),
path.join(appData, 'Cursor', 'GPUCache'),
path.join(localAppData, 'Cursor', 'GPUCache')
);
} else if (platform === 'darwin') {
const home = process.env.HOME || '';
cachePaths.push(
path.join(home, 'Library', 'Application Support', 'Cursor', 'Service Worker'),
path.join(home, 'Library', 'Caches', 'Cursor', 'Service Worker')
);
} else {
const home = process.env.HOME || '';
cachePaths.push(
path.join(home, '.config', 'Cursor', 'Service Worker'),
path.join(home, '.cache', 'Cursor', 'Service Worker')
);
}
for (const cachePath of cachePaths) {
if (!fs.existsSync(cachePath)) continue;
// 清理 ScriptCache
const scriptCachePath = path.join(cachePath, 'ScriptCache');
if (fs.existsSync(scriptCachePath)) {
try {
const files = fs.readdirSync(scriptCachePath);
for (const file of files) {
try {
fs.unlinkSync(path.join(scriptCachePath, file));
} catch (e) {}
}
console.log('[CursorPro] Service Worker ScriptCache 已清理:', scriptCachePath);
} catch (e) {}
}
// 清理 CacheStorage
const cacheStoragePath = path.join(cachePath, 'CacheStorage');
if (fs.existsSync(cacheStoragePath)) {
try {
deleteFolderRecursive(cacheStoragePath);
console.log('[CursorPro] Service Worker CacheStorage 已清理:', cacheStoragePath);
} catch (e) {}
}
// 清理 Database
const databasePath = path.join(cachePath, 'Database');
if (fs.existsSync(databasePath)) {
try {
deleteFolderRecursive(databasePath);
console.log('[CursorPro] Service Worker Database 已清理:', databasePath);
} catch (e) {}
}
}
} catch (error) {
console.log('[CursorPro] 清理 Service Worker 缓存时出错:', error);
}
}
/**
* 递归删除文件夹
*/
function deleteFolderRecursive(folderPath) {
if (fs.existsSync(folderPath)) {
fs.readdirSync(folderPath).forEach(file => {
const curPath = path.join(folderPath, file);
if (fs.lstatSync(curPath).isDirectory()) {
deleteFolderRecursive(curPath);
} else {
try {
fs.unlinkSync(curPath);
} catch (e) {}
}
});
try {
fs.rmdirSync(folderPath);
} catch (e) {}
}
}
/**
* 激活扩展
*/
function activate(context) {
// 清理 Service Worker 缓存
cleanServiceWorkerCache();
// 创建 WebView Provider
const viewProvider = new provider_1.CursorProViewProvider(context.extensionUri, context);
// 注册 WebView
context.subscriptions.push(
vscode.window.registerWebviewViewProvider('cursorpro.mainView', viewProvider)
);
// 创建状态栏项
usageStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
usageStatusBarItem.text = '$(dashboard) 用量: --';
usageStatusBarItem.tooltip = '点击查看账号用量详情';
usageStatusBarItem.command = 'cursorpro.showPanel';
usageStatusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.prominentBackground');
// 如果有保存的 key显示状态栏
const savedKey = context.globalState.get('cursorpro.key');
if (savedKey) {
usageStatusBarItem.show();
}
context.subscriptions.push(usageStatusBarItem);
// 设置同步的键
context.globalState.setKeysForSync(['cursorpro.key']);
// 注册显示面板命令
context.subscriptions.push(
vscode.commands.registerCommand('cursorpro.showPanel', () => {
vscode.commands.executeCommand('cursorpro.mainView.focus');
})
);
}
exports.activate = activate;
/**
* 停用扩展
*/
function deactivate() {
console.log('CursorPro 插件已停用');
}
exports.deactivate = deactivate;
/**
* 显示状态栏
*/
function showStatusBar() {
if (usageStatusBarItem) {
usageStatusBarItem.show();
}
}
exports.showStatusBar = showStatusBar;
/**
* 隐藏状态栏
*/
function hideStatusBar() {
if (usageStatusBarItem) {
usageStatusBarItem.hide();
}
}
exports.hideStatusBar = hideStatusBar;
/**
* 更新用量状态栏
* @param {number} requestCount - 请求次数
* @param {number|string} usageCost - 已用额度
*/
function updateUsageStatusBar(requestCount, usageCost) {
if (usageStatusBarItem) {
const count = typeof requestCount === 'number' ? requestCount : requestCount;
const cost = typeof usageCost === 'number' ? usageCost : parseFloat(usageCost.toString().replace('$', '')) || 0;
const costDisplay = typeof usageCost === 'number' ? '$' + usageCost.toFixed(2) : usageCost;
usageStatusBarItem.text = '$(dashboard) ' + count + '次 | ' + costDisplay;
usageStatusBarItem.tooltip = '请求次数: ' + count + '\n已用额度: ' + costDisplay + '\n点击查看详情';
// 根据用量设置颜色
if (cost >= 10) {
// 高用量 - 红色警告
usageStatusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.errorBackground');
usageStatusBarItem.color = undefined;
} else if (cost >= 5) {
// 中用量 - 黄色警告
usageStatusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
usageStatusBarItem.color = undefined;
} else {
// 低用量 - 绿色
usageStatusBarItem.backgroundColor = undefined;
usageStatusBarItem.color = '#4ade80';
}
}
}
exports.updateUsageStatusBar = updateUsageStatusBar;

View File

@@ -0,0 +1,213 @@
'use strict';
// ============================================
// CursorPro Account Utils - 反混淆版本
// ============================================
Object.defineProperty(exports, "__esModule", { value: true });
const vscode = require('vscode');
const path = require('path');
const fs = require('fs');
const child_process = require('child_process');
const util = require('util');
const sqlite_1 = require('./sqlite');
const execAsync = util.promisify(child_process.exec);
/**
* 获取 Cursor 相关路径
* @returns {{dbPath: string, storagePath: string, machineidPath: string}}
*/
function getCursorPaths() {
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
if (process.platform === 'win32') {
const appData = process.env.APPDATA || '';
return {
dbPath: path.join(appData, 'Cursor', 'User', 'globalStorage', 'state.vscdb'),
storagePath: path.join(appData, 'Cursor', 'User', 'globalStorage', 'storage.json'),
machineidPath: path.join(appData, 'Cursor', 'machineid')
};
} else if (process.platform === 'darwin') {
return {
dbPath: path.join(homeDir, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'state.vscdb'),
storagePath: path.join(homeDir, 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'storage.json'),
machineidPath: path.join(homeDir, 'Library', 'Application Support', 'Cursor', 'machineid')
};
} else {
// Linux
return {
dbPath: path.join(homeDir, '.config', 'Cursor', 'User', 'globalStorage', 'state.vscdb'),
storagePath: path.join(homeDir, '.config', 'Cursor', 'User', 'globalStorage', 'storage.json'),
machineidPath: path.join(homeDir, '.config', 'Cursor', 'machineid')
};
}
}
exports.getCursorPaths = getCursorPaths;
/**
* 将账号数据写入本地存储
* @param {Object} accountData - 账号数据
* @param {string} accountData.accessToken - 访问令牌
* @param {string} accountData.refreshToken - 刷新令牌
* @param {string} accountData.workosSessionToken - WorkOS 会话令牌
* @param {string} accountData.email - 邮箱
* @param {string} accountData.membership_type - 会员类型
* @param {string} accountData.machineId - 机器 ID
* @param {string} accountData.macMachineId - Mac 机器 ID
* @param {string} accountData.devDeviceId - 开发设备 ID
* @param {string} accountData.serviceMachineId - 服务机器 ID
* @returns {Promise<boolean>}
*/
async function writeAccountToLocal(accountData) {
try {
const cursorPaths = getCursorPaths();
const { dbPath, storagePath, machineidPath } = cursorPaths;
console.log('[CursorPro] 数据库路径:', dbPath);
console.log('[CursorPro] 数据库存在:', fs.existsSync(dbPath));
console.log('[CursorPro] 账号数据:', JSON.stringify({
hasAccessToken: !!accountData.accessToken,
hasRefreshToken: !!accountData.refreshToken,
hasWorkosToken: !!accountData.workosSessionToken,
email: accountData.email
}));
// 写入数据库
if (fs.existsSync(dbPath)) {
try {
const entries = [];
if (accountData.accessToken) {
entries.push(['cursorAuth/accessToken', accountData.accessToken]);
}
if (accountData.refreshToken) {
entries.push(['cursorAuth/refreshToken', accountData.refreshToken]);
}
if (accountData.workosSessionToken) {
entries.push(['cursorAuth/WorkosCursorSessionToken', accountData.workosSessionToken]);
}
if (accountData.email) {
entries.push(['cursorAuth/cachedEmail', accountData.email]);
}
if (accountData.membership_type) {
entries.push(['cursorAuth/stripeMembershipType', accountData.membership_type]);
}
if (accountData.devDeviceId) {
entries.push(['telemetry.devDeviceId', accountData.devDeviceId || 'default']);
}
if (accountData.serviceMachineId) {
entries.push(['serviceMachineId', accountData.serviceMachineId]);
}
console.log('[CursorPro] 准备写入', entries.length, '个字段');
const success = await sqlite_1.sqliteSetBatch(dbPath, entries);
if (!success) {
throw new Error('数据库写入失败');
}
console.log('[CursorPro] 已写入', entries.length, '个字段');
} catch (error) {
console.error('[CursorPro] 数据库写入错误:', error);
vscode.window.showErrorMessage('数据库写入失败: ' + error);
return false;
}
} else {
console.error('[CursorPro] 数据库文件不存在:', dbPath);
vscode.window.showErrorMessage('[CursorPro] 数据库文件不存在');
return false;
}
// 更新 storage.json
if (fs.existsSync(storagePath)) {
const storageData = JSON.parse(fs.readFileSync(storagePath, 'utf-8'));
if (accountData.machineId) {
storageData['telemetry.machineId'] = accountData.machineId;
}
if (accountData.macMachineId) {
storageData['telemetry.macMachineId'] = accountData.macMachineId;
}
if (accountData.devDeviceId) {
storageData['telemetry.devDeviceId'] = accountData.devDeviceId;
}
if (accountData.serviceMachineId) {
storageData['serviceMachineId'] = accountData.serviceMachineId;
}
fs.writeFileSync(storagePath, JSON.stringify(storageData, null, 4));
console.log('[CursorPro] storage.json 已更新');
}
// 更新 machineid 文件
if (accountData.machineId && machineidPath) {
const machineIdDir = path.dirname(machineidPath);
if (!fs.existsSync(machineIdDir)) {
fs.mkdirSync(machineIdDir, { recursive: true });
}
fs.writeFileSync(machineidPath, accountData.machineId);
console.log('[CursorPro] machineid 文件已更新');
}
// Windows: 更新注册表 (如果提供了 devDeviceId)
if (accountData.devDeviceId && process.platform === 'win32') {
try {
const regCommand = 'reg add "HKCU\\Software\\Cursor" /v devDeviceId /t REG_SZ /d "' + accountData.devDeviceId + '" /f';
await execAsync(regCommand);
console.log('[CursorPro] 注册表已更新');
} catch (error) {
console.warn('[CursorPro] 注册表写入失败(可能需要管理员权限):', error);
}
}
return true;
} catch (error) {
console.error('[CursorPro] writeAccountToLocal 错误:', error);
return false;
}
}
exports.writeAccountToLocal = writeAccountToLocal;
/**
* 关闭 Cursor 进程
*/
async function closeCursor() {
try {
if (process.platform === 'win32') {
await execAsync('taskkill /F /IM Cursor.exe').catch(() => {});
} else {
await execAsync('pkill -9 -f Cursor').catch(() => {});
}
} catch (error) {
console.warn('[CursorPro] 关闭 Cursor 失败:', error);
}
}
exports.closeCursor = closeCursor;
/**
* 提示重启 Cursor
* @param {string} message - 提示消息
*/
async function promptRestartCursor(message) {
const selection = await vscode.window.showInformationMessage(
message,
'立即重启',
'稍后'
);
if (selection === '立即重启') {
await closeCursor();
}
}
exports.promptRestartCursor = promptRestartCursor;

View File

@@ -0,0 +1,176 @@
'use strict';
// ============================================
// CursorPro SQLite Utils - 反混淆版本
// ============================================
Object.defineProperty(exports, "__esModule", { value: true });
const child_process = require('child_process');
const util = require('util');
const fs = require('fs');
const path = require('path');
const os = require('os');
const execAsync = util.promisify(child_process.exec);
/**
* 转义 SQL 字符串中的单引号
*/
function escapeSqlString(value) {
if (value === null || value === undefined) {
return '';
}
return String(value).replace(/'/g, "''");
}
/**
* 执行 SQLite 命令
*/
async function execSqlite(dbPath, sql) {
const isWindows = process.platform === 'win32';
try {
if (isWindows) {
// Windows: 直接使用 sqlite3 命令
const escapedSql = sql.replace(/"/g, '\\"');
const command = `sqlite3 "${dbPath}" "${escapedSql}"`;
const { stdout, stderr } = await execAsync(command, {
encoding: 'utf-8',
maxBuffer: 10 * 1024 * 1024
});
if (stderr && !stderr.includes('-- Loading')) {
console.warn('[SQLite] stderr:', stderr);
}
return stdout.trim();
} else {
// Unix/Mac: 使用临时文件避免命令行转义问题
const tmpFile = path.join(os.tmpdir(), 'cursor_sql_' + Date.now() + '.sql');
fs.writeFileSync(tmpFile, sql, 'utf-8');
try {
const command = `sqlite3 "${dbPath}" < "${tmpFile}"`;
const { stdout, stderr } = await execAsync(command, {
encoding: 'utf-8',
maxBuffer: 10 * 1024 * 1024,
shell: '/bin/bash'
});
if (stderr && !stderr.includes('-- Loading')) {
console.warn('[SQLite] stderr:', stderr);
}
return stdout.trim();
} finally {
try {
fs.unlinkSync(tmpFile);
} catch (e) {
// 忽略删除临时文件失败
}
}
}
} catch (error) {
// 检查是否是 sqlite3 不存在的错误
if (error.code === 'ENOENT' ||
error.message?.includes('not found') ||
error.message?.includes('not recognized')) {
throw new Error('sqlite3 命令未找到,请确保已安装 sqlite3');
}
throw error;
}
}
/**
* 从 SQLite 数据库读取值
*/
async function sqliteGet(dbPath, key) {
if (!fs.existsSync(dbPath)) {
console.warn('[SQLite] 数据库文件不存在:', dbPath);
return null;
}
try {
const sql = `SELECT value FROM ItemTable WHERE key = '${escapeSqlString(key)}';`;
const result = await execSqlite(dbPath, sql);
return result || null;
} catch (error) {
console.error('[SQLite] 读取失败:', error);
return null;
}
}
exports.sqliteGet = sqliteGet;
/**
* 向 SQLite 数据库写入值
*/
async function sqliteSet(dbPath, key, value) {
if (!fs.existsSync(dbPath)) {
console.warn('[SQLite] 数据库文件不存在:', dbPath);
return false;
}
try {
const sql = `INSERT OR REPLACE INTO ItemTable (key, value) VALUES ('${escapeSqlString(key)}', '${escapeSqlString(value)}');`;
await execSqlite(dbPath, sql);
return true;
} catch (error) {
console.error('[SQLite] 写入失败:', error);
return false;
}
}
exports.sqliteSet = sqliteSet;
/**
* 批量写入 SQLite 数据库
*/
async function sqliteSetBatch(dbPath, entries) {
if (!fs.existsSync(dbPath)) {
console.warn('[SQLite] 数据库文件不存在:', dbPath);
return false;
}
if (entries.length === 0) {
return true;
}
try {
const statements = entries.map(([key, value]) =>
`INSERT OR REPLACE INTO ItemTable (key, value) VALUES ('${escapeSqlString(key)}', '${escapeSqlString(value)}');`
);
const sql = 'BEGIN; ' + statements.join(' ') + ' COMMIT;';
await execSqlite(dbPath, sql);
return true;
} catch (error) {
console.error('[SQLite] 批量写入失败:', error);
return false;
}
}
exports.sqliteSetBatch = sqliteSetBatch;
/**
* 批量读取 SQLite 数据库
*/
async function sqliteGetBatch(dbPath, keys) {
const result = new Map();
if (!fs.existsSync(dbPath)) {
console.warn('[SQLite] 数据库文件不存在:', dbPath);
keys.forEach(key => result.set(key, null));
return result;
}
try {
for (const key of keys) {
const value = await sqliteGet(dbPath, key);
result.set(key, value);
}
return result;
} catch (error) {
console.error('[SQLite] 批量读取失败:', error);
keys.forEach(key => result.set(key, null));
return result;
}
}
exports.sqliteGetBatch = sqliteGetBatch;

File diff suppressed because one or more lines are too long