dasdasd
This commit is contained in:
parent
fb68de0206
commit
06d39edb64
29
batch-start.js
Normal file
29
batch-start.js
Normal file
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 批量注册启动脚本
|
||||
*/
|
||||
|
||||
require('dotenv').config();
|
||||
const BatchRegister = require('./src/tools/account-register/batch-register');
|
||||
|
||||
// 配置你的3个 AdsPower Profile ID
|
||||
const PROFILES = [
|
||||
'k172d58u',
|
||||
'k172d4mb',
|
||||
'k1728p8l'
|
||||
];
|
||||
|
||||
// 启动批量注册
|
||||
const batch = new BatchRegister({
|
||||
profiles: PROFILES, // 3个profile
|
||||
concurrency: 1, // 并发3个
|
||||
maxCount: Infinity, // 无限循环
|
||||
delayBetweenRuns: 10000, // 批次间隔10秒
|
||||
maxRetries: 3, // 单次失败重试3次
|
||||
retryDelay: 30000 // 重试间隔30秒
|
||||
});
|
||||
|
||||
batch.start().catch(error => {
|
||||
console.error('批量注册异常:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
206
src/tools/account-register/batch-register.js
Normal file
206
src/tools/account-register/batch-register.js
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
* Batch Register - 批量自动注册(支持并发)
|
||||
*/
|
||||
|
||||
const logger = require('../../shared/logger');
|
||||
const WindsurfRegister = require('./sites/windsurf');
|
||||
|
||||
class BatchRegister {
|
||||
constructor(options = {}) {
|
||||
// AdsPower profile配置
|
||||
this.profiles = options.profiles || [process.env.ADSPOWER_USER_ID];
|
||||
this.concurrency = Math.min(options.concurrency || 1, this.profiles.length);
|
||||
|
||||
// 执行配置
|
||||
this.maxCount = options.maxCount || Infinity;
|
||||
this.delayBetweenRuns = options.delayBetweenRuns || 10000;
|
||||
this.maxRetries = options.maxRetries || 3;
|
||||
this.retryDelay = options.retryDelay || 30000;
|
||||
|
||||
// 统计数据
|
||||
this.stats = {
|
||||
total: 0,
|
||||
success: 0,
|
||||
failed: 0,
|
||||
running: 0,
|
||||
startTime: null
|
||||
};
|
||||
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行单次注册(带重试)
|
||||
*/
|
||||
async runOnce(profileId, taskId) {
|
||||
let retryCount = 0;
|
||||
|
||||
while (retryCount < this.maxRetries) {
|
||||
try {
|
||||
logger.info('BatchRegister', `\n${'='.repeat(60)}`);
|
||||
logger.info('BatchRegister', `[任务${taskId}] 使用Profile: ${profileId}`);
|
||||
logger.info('BatchRegister', `[任务${taskId}] 第 ${this.stats.total + 1} 次注册 (重试: ${retryCount}/${this.maxRetries})`);
|
||||
logger.info('BatchRegister', `${'='.repeat(60)}\n`);
|
||||
|
||||
this.stats.running++;
|
||||
|
||||
const register = new WindsurfRegister({ adspowerUserId: profileId });
|
||||
const result = await register.register();
|
||||
|
||||
this.stats.running--;
|
||||
|
||||
if (result.success) {
|
||||
this.stats.success++;
|
||||
logger.success('BatchRegister', `[任务${taskId}] ✓ 注册成功!邮箱: ${result.account.email}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.stats.running--;
|
||||
retryCount++;
|
||||
logger.error('BatchRegister', `[任务${taskId}] 注册失败: ${error.message}`);
|
||||
|
||||
if (retryCount < this.maxRetries) {
|
||||
logger.warn('BatchRegister', `[任务${taskId}] ${this.retryDelay/1000}秒后进行第 ${retryCount + 1} 次重试...`);
|
||||
await this.delay(this.retryDelay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 所有重试都失败
|
||||
this.stats.failed++;
|
||||
logger.error('BatchRegister', `[任务${taskId}] ✗ 注册失败,已达最大重试次数 (${this.maxRetries})`);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟函数
|
||||
*/
|
||||
async delay(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时长
|
||||
*/
|
||||
formatDuration(ms) {
|
||||
const seconds = Math.floor(ms / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours}小时${minutes % 60}分钟`;
|
||||
} else if (minutes > 0) {
|
||||
return `${minutes}分钟${seconds % 60}秒`;
|
||||
} else {
|
||||
return `${seconds}秒`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印统计信息
|
||||
*/
|
||||
printStats() {
|
||||
const duration = Date.now() - this.stats.startTime;
|
||||
const successRate = this.stats.total > 0
|
||||
? ((this.stats.success / this.stats.total) * 100).toFixed(2)
|
||||
: 0;
|
||||
|
||||
logger.info('BatchRegister', '\n' + '='.repeat(60));
|
||||
logger.info('BatchRegister', '📊 批量注册统计');
|
||||
logger.info('BatchRegister', '='.repeat(60));
|
||||
logger.info('BatchRegister', `⏱️ 运行时长: ${this.formatDuration(duration)}`);
|
||||
logger.info('BatchRegister', `🔄 并发数: ${this.concurrency} (Profiles: ${this.profiles.length}个)`);
|
||||
logger.info('BatchRegister', `🏃 运行中: ${this.stats.running}`);
|
||||
logger.info('BatchRegister', `📈 总次数: ${this.stats.total}`);
|
||||
logger.info('BatchRegister', `✅ 成功: ${this.stats.success} (${successRate}%)`);
|
||||
logger.info('BatchRegister', `❌ 失败: ${this.stats.failed}`);
|
||||
logger.info('BatchRegister', `⚡ 平均耗时: ${this.stats.total > 0 ? this.formatDuration(duration / this.stats.total) : '0秒'}`);
|
||||
logger.info('BatchRegister', '='.repeat(60) + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动批量注册(并发版本)
|
||||
*/
|
||||
async start() {
|
||||
this.running = true;
|
||||
this.stats.startTime = Date.now();
|
||||
|
||||
logger.info('BatchRegister', '\n🚀 批量注册启动');
|
||||
logger.info('BatchRegister', `目标次数: ${this.maxCount === Infinity ? '无限' : this.maxCount}`);
|
||||
logger.info('BatchRegister', `并发数: ${this.concurrency}`);
|
||||
logger.info('BatchRegister', `Profiles: ${this.profiles.join(', ')}`);
|
||||
logger.info('BatchRegister', `注册间隔: ${this.delayBetweenRuns/1000}秒`);
|
||||
logger.info('BatchRegister', `单次重试: ${this.maxRetries}次\n`);
|
||||
|
||||
// 捕获 Ctrl+C
|
||||
process.on('SIGINT', async () => {
|
||||
logger.warn('BatchRegister', '\n\n⚠️ 收到停止信号,等待当前任务完成...');
|
||||
this.running = false;
|
||||
});
|
||||
|
||||
// 并发控制:使用 profile 池
|
||||
const tasks = [];
|
||||
let profileIndex = 0;
|
||||
|
||||
while (this.running && this.stats.total < this.maxCount) {
|
||||
// 如果当前运行任务数 < 并发数,启动新任务
|
||||
while (tasks.length < this.concurrency && this.stats.total < this.maxCount && this.running) {
|
||||
this.stats.total++;
|
||||
const taskId = this.stats.total;
|
||||
const profileId = this.profiles[profileIndex % this.profiles.length];
|
||||
profileIndex++;
|
||||
|
||||
const task = this.runOnce(profileId, taskId).then((success) => {
|
||||
// 任务完成后,从任务列表中移除
|
||||
const index = tasks.indexOf(task);
|
||||
if (index > -1) {
|
||||
tasks.splice(index, 1);
|
||||
}
|
||||
return success;
|
||||
});
|
||||
|
||||
tasks.push(task);
|
||||
|
||||
// 短暂延迟,避免同时启动
|
||||
await this.delay(1000);
|
||||
}
|
||||
|
||||
// 等待至少一个任务完成
|
||||
if (tasks.length > 0) {
|
||||
await Promise.race(tasks);
|
||||
}
|
||||
|
||||
// 定期打印统计(每完成5次)
|
||||
if (this.stats.total % 5 === 0 && tasks.length === 0) {
|
||||
this.printStats();
|
||||
}
|
||||
|
||||
// 任务间隔
|
||||
if (tasks.length === 0 && this.running && this.stats.total < this.maxCount) {
|
||||
logger.info('BatchRegister', `⏳ 等待 ${this.delayBetweenRuns/1000} 秒后继续...\n`);
|
||||
await this.delay(this.delayBetweenRuns);
|
||||
}
|
||||
}
|
||||
|
||||
// 等待所有剩余任务完成
|
||||
if (tasks.length > 0) {
|
||||
logger.info('BatchRegister', `等待 ${tasks.length} 个任务完成...`);
|
||||
await Promise.all(tasks);
|
||||
}
|
||||
|
||||
// 结束统计
|
||||
this.printStats();
|
||||
logger.success('BatchRegister', '🎉 批量注册完成!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止批量注册
|
||||
*/
|
||||
stop() {
|
||||
this.running = false;
|
||||
logger.warn('BatchRegister', '⚠️ 正在停止批量注册...');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BatchRegister;
|
||||
@ -20,7 +20,7 @@ const CardGenerator = require('../../card-generator/generator');
|
||||
const database = require('../../database');
|
||||
|
||||
class WindsurfRegister {
|
||||
constructor() {
|
||||
constructor(options = {}) {
|
||||
this.siteName = 'Windsurf';
|
||||
this.siteUrl = 'https://windsurf.com/account/register';
|
||||
this.dataGen = new AccountDataGenerator();
|
||||
@ -31,6 +31,9 @@ class WindsurfRegister {
|
||||
this.currentStep = 0;
|
||||
this.accountData = null;
|
||||
|
||||
// AdsPower配置(支持多profile并发)
|
||||
this.adspowerUserId = options.adspowerUserId || process.env.ADSPOWER_USER_ID;
|
||||
|
||||
// 记录注册时间和额外信息
|
||||
this.registrationTime = null;
|
||||
this.quotaInfo = null;
|
||||
@ -194,12 +197,12 @@ class WindsurfRegister {
|
||||
logger.info(this.siteName, '启动 AdsPower 指纹浏览器...');
|
||||
|
||||
// 检查 AdsPower 配置
|
||||
const adspowerUserId = process.env.ADSPOWER_USER_ID;
|
||||
const adspowerUserId = this.adspowerUserId;
|
||||
if (!adspowerUserId) {
|
||||
logger.error(this.siteName, '');
|
||||
logger.error(this.siteName, '❌ 未配置 ADSPOWER_USER_ID');
|
||||
logger.error(this.siteName, '');
|
||||
logger.error(this.siteName, '请在 .env 文件中配置:');
|
||||
logger.error(this.siteName, '请在 .env 文件中配置或传入 options.adspowerUserId:');
|
||||
logger.error(this.siteName, 'ADSPOWER_USER_ID=your_profile_id');
|
||||
logger.error(this.siteName, '');
|
||||
throw new Error('未配置 AdsPower 用户ID');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user