mirror of
https://github.com/yeongpin/cursor-free-vip.git
synced 2025-08-02 20:47:35 +08:00
fix: add retry logic for human verification failures
This commit is contained in:
parent
93f4f05ac4
commit
e58acce44e
@ -170,7 +170,9 @@
|
||||
"password_submitted": "Password Submitted",
|
||||
"total_usage": "Total Usage: {usage}",
|
||||
"setting_on_password": "Setting Password",
|
||||
"getting_code": "Getting Verification Code, Will Try in 60s"
|
||||
"getting_code": "Getting Verification Code, Will Try in 60s",
|
||||
"human_verify_error": "Can't verify the user is human. Retrying...",
|
||||
"max_retries_reached": "Maximum retry attempts reached. Registration failed."
|
||||
},
|
||||
"auth": {
|
||||
"title": "Cursor Auth Manager",
|
||||
|
316
new_signup.py
316
new_signup.py
@ -39,7 +39,7 @@ def signal_handler(signum, frame):
|
||||
os._exit(0)
|
||||
|
||||
def simulate_human_input(page, url, config, translator=None):
|
||||
"""Visit URL"""
|
||||
"""Visit URL with human-like behavior"""
|
||||
if translator:
|
||||
print(f"{Fore.CYAN}🚀 {translator.get('register.visiting_url')}: {url}{Style.RESET_ALL}")
|
||||
|
||||
@ -47,53 +47,194 @@ def simulate_human_input(page, url, config, translator=None):
|
||||
page.get('about:blank')
|
||||
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
||||
|
||||
# Add random mouse movements before visiting target page
|
||||
try:
|
||||
page.run_js("""
|
||||
function simulateMouseMovement() {
|
||||
const points = [];
|
||||
const numPoints = Math.floor(Math.random() * 10) + 5;
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
points.push({
|
||||
x: Math.random() * window.innerWidth,
|
||||
y: Math.random() * window.innerHeight
|
||||
});
|
||||
}
|
||||
points.forEach((point, i) => {
|
||||
setTimeout(() => {
|
||||
const event = new MouseEvent('mousemove', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: point.x,
|
||||
clientY: point.y
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
}, i * (Math.random() * 200 + 50));
|
||||
});
|
||||
}
|
||||
simulateMouseMovement();
|
||||
""")
|
||||
except:
|
||||
pass # Ignore if JavaScript execution fails
|
||||
|
||||
# Visit target page
|
||||
page.get(url)
|
||||
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
||||
|
||||
# Add some random scrolling
|
||||
try:
|
||||
page.run_js("""
|
||||
function simulateHumanScroll() {
|
||||
const maxScroll = Math.max(
|
||||
document.body.scrollHeight,
|
||||
document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight,
|
||||
document.documentElement.offsetHeight,
|
||||
document.body.clientHeight,
|
||||
document.documentElement.clientHeight
|
||||
);
|
||||
const scrollPoints = [];
|
||||
const numPoints = Math.floor(Math.random() * 3) + 2;
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
scrollPoints.push(Math.floor(Math.random() * maxScroll));
|
||||
}
|
||||
scrollPoints.sort((a, b) => a - b);
|
||||
scrollPoints.forEach((point, i) => {
|
||||
setTimeout(() => {
|
||||
window.scrollTo({
|
||||
top: point,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}, i * (Math.random() * 1000 + 500));
|
||||
});
|
||||
}
|
||||
simulateHumanScroll();
|
||||
""")
|
||||
except:
|
||||
pass # Ignore if JavaScript execution fails
|
||||
|
||||
def simulate_human_typing(element, text, config):
|
||||
"""Simulate human-like typing with random delays between keystrokes"""
|
||||
for char in text:
|
||||
element.input(char)
|
||||
# Random delay between keystrokes (30-100ms)
|
||||
time.sleep(random.uniform(0.03, 0.1))
|
||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||
|
||||
def fill_signup_form(page, first_name, last_name, email, config, translator=None):
|
||||
"""Fill signup form"""
|
||||
try:
|
||||
if translator:
|
||||
print(f"{Fore.CYAN}📧 {translator.get('register.filling_form')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print("\n正在填写注册表单...")
|
||||
|
||||
# Fill first name
|
||||
first_name_input = page.ele("@name=first_name")
|
||||
if first_name_input:
|
||||
first_name_input.input(first_name)
|
||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||
|
||||
# Fill last name
|
||||
last_name_input = page.ele("@name=last_name")
|
||||
if last_name_input:
|
||||
last_name_input.input(last_name)
|
||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||
|
||||
# Fill email
|
||||
email_input = page.ele("@name=email")
|
||||
if email_input:
|
||||
email_input.input(email)
|
||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||
|
||||
# Click submit button
|
||||
submit_button = page.ele("@type=submit")
|
||||
if submit_button:
|
||||
submit_button.click()
|
||||
time.sleep(get_random_wait_time(config, 'submit_wait'))
|
||||
"""Fill signup form with human-like behavior"""
|
||||
max_retries = 5
|
||||
retry_count = 0
|
||||
|
||||
while retry_count < max_retries:
|
||||
try:
|
||||
if translator:
|
||||
print(f"{Fore.CYAN}📧 {translator.get('register.filling_form')} (Attempt {retry_count + 1}/{max_retries}){Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"\n正在填写注册表单... (Attempt {retry_count + 1}/{max_retries})")
|
||||
|
||||
# Add random initial delay
|
||||
time.sleep(random.uniform(0.5, 1.5))
|
||||
|
||||
# Fill first name with human-like typing
|
||||
first_name_input = page.ele("@name=first_name")
|
||||
if first_name_input:
|
||||
simulate_human_typing(first_name_input, first_name, config)
|
||||
# Add random pause between fields
|
||||
time.sleep(random.uniform(0.3, 0.8))
|
||||
|
||||
# Fill last name with human-like typing
|
||||
last_name_input = page.ele("@name=last_name")
|
||||
if last_name_input:
|
||||
simulate_human_typing(last_name_input, last_name, config)
|
||||
# Add random pause between fields
|
||||
time.sleep(random.uniform(0.3, 0.8))
|
||||
|
||||
# Fill email with human-like typing
|
||||
email_input = page.ele("@name=email")
|
||||
if email_input:
|
||||
simulate_human_typing(email_input, email, config)
|
||||
# Add random pause before submitting
|
||||
time.sleep(random.uniform(0.5, 1.2))
|
||||
|
||||
# Move mouse to submit button with human-like movement
|
||||
submit_button = page.ele("@type=submit")
|
||||
if submit_button:
|
||||
try:
|
||||
# Simulate mouse movement to button
|
||||
page.run_js("""
|
||||
function moveToButton(button) {
|
||||
const rect = button.getBoundingClientRect();
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
|
||||
// Create a curved path to the button
|
||||
const startX = Math.random() * window.innerWidth;
|
||||
const startY = Math.random() * window.innerHeight;
|
||||
const controlX = (startX + centerX) / 2 + (Math.random() - 0.5) * 100;
|
||||
const controlY = (startY + centerY) / 2 + (Math.random() - 0.5) * 100;
|
||||
|
||||
const steps = 20;
|
||||
for (let i = 0; i <= steps; i++) {
|
||||
const t = i / steps;
|
||||
const x = Math.pow(1-t, 2) * startX + 2 * (1-t) * t * controlX + Math.pow(t, 2) * centerX;
|
||||
const y = Math.pow(1-t, 2) * startY + 2 * (1-t) * t * controlY + Math.pow(t, 2) * centerY;
|
||||
|
||||
setTimeout(() => {
|
||||
const event = new MouseEvent('mousemove', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: x,
|
||||
clientY: y
|
||||
});
|
||||
document.dispatchEvent(event);
|
||||
}, i * (Math.random() * 20 + 10));
|
||||
}
|
||||
}
|
||||
moveToButton(document.querySelector('button[type="submit"]'));
|
||||
""")
|
||||
time.sleep(random.uniform(0.3, 0.6))
|
||||
except:
|
||||
pass # Ignore if JavaScript execution fails
|
||||
|
||||
submit_button.click()
|
||||
time.sleep(get_random_wait_time(config, 'submit_wait'))
|
||||
|
||||
# Check for human verification error
|
||||
error_message = page.ele("text:Can't verify the user is human")
|
||||
if error_message:
|
||||
if translator:
|
||||
print(f"{Fore.YELLOW}⚠️ {translator.get('register.human_verify_error')} (Attempt {retry_count + 1}/{max_retries}){Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"Can't verify the user is human. Retrying... (Attempt {retry_count + 1}/{max_retries})")
|
||||
retry_count += 1
|
||||
# Add longer random delay between retries
|
||||
time.sleep(random.uniform(2, 4))
|
||||
continue
|
||||
|
||||
if translator:
|
||||
print(f"{Fore.GREEN}✅ {translator.get('register.form_success')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print("Form filled successfully")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
if translator:
|
||||
print(f"{Fore.RED}❌ {translator.get('register.form_error', error=str(e))}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"Error filling form: {e}")
|
||||
retry_count += 1
|
||||
if retry_count < max_retries:
|
||||
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
||||
continue
|
||||
return False
|
||||
|
||||
if retry_count >= max_retries:
|
||||
if translator:
|
||||
print(f"{Fore.GREEN}✅ {translator.get('register.form_success')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}❌ {translator.get('register.max_retries_reached')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print("Form filled successfully")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
if translator:
|
||||
print(f"{Fore.RED}❌ {translator.get('register.form_error', error=str(e))}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"Error filling form: {e}")
|
||||
print("Maximum retry attempts reached. Registration failed.")
|
||||
return False
|
||||
|
||||
def get_default_chrome_path():
|
||||
@ -163,7 +304,7 @@ def get_random_wait_time(config, timing_type='page_load_wait'):
|
||||
return random.uniform(0.1, 0.8) # Return default value when error
|
||||
|
||||
def setup_driver(translator=None):
|
||||
"""Setup browser driver"""
|
||||
"""Setup browser driver with randomized fingerprint"""
|
||||
try:
|
||||
# Get config
|
||||
config = get_config(translator)
|
||||
@ -185,10 +326,42 @@ def setup_driver(translator=None):
|
||||
# Use incognito mode
|
||||
co.set_argument("--incognito")
|
||||
|
||||
# Set random port
|
||||
co.set_argument("--no-sandbox")
|
||||
# Randomize browser fingerprint
|
||||
# Random screen resolution
|
||||
resolutions = [
|
||||
"1920,1080", "1366,768", "1536,864", "1440,900",
|
||||
"1280,720", "1600,900", "1024,768", "1680,1050"
|
||||
]
|
||||
window_size = random.choice(resolutions)
|
||||
co.set_argument(f"--window-size={window_size}")
|
||||
|
||||
# Random user agent
|
||||
user_agents = [
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||
]
|
||||
co.set_argument(f"--user-agent={random.choice(user_agents)}")
|
||||
|
||||
# Random color depth
|
||||
color_depths = ["24", "30", "48"]
|
||||
co.set_argument(f"--color-depth={random.choice(color_depths)}")
|
||||
|
||||
# Additional fingerprint randomization
|
||||
co.set_argument("--disable-blink-features=AutomationControlled") # Hide automation
|
||||
co.set_argument("--disable-features=IsolateOrigins,site-per-process")
|
||||
|
||||
# Random platform
|
||||
platforms = ["Win32", "Win64", "MacIntel", "Linux x86_64"]
|
||||
co.set_argument(f"--platform={random.choice(platforms)}")
|
||||
|
||||
# Random language
|
||||
languages = ["en-US", "en-GB", "fr-FR", "de-DE", "es-ES", "it-IT"]
|
||||
co.set_argument(f"--lang={random.choice(languages)}")
|
||||
|
||||
# Set random port
|
||||
co.set_argument("--no-sandbox")
|
||||
co.auto_port()
|
||||
|
||||
# Use headless mode (must be set to False, simulate human operation)
|
||||
@ -212,6 +385,63 @@ def setup_driver(translator=None):
|
||||
print("Starting browser...")
|
||||
|
||||
page = ChromiumPage(co)
|
||||
|
||||
# Additional JavaScript-based fingerprint randomization
|
||||
try:
|
||||
page.run_js("""
|
||||
// Override navigator properties
|
||||
const originalNavigator = window.navigator;
|
||||
const navigatorProxy = new Proxy(originalNavigator, {
|
||||
get: function(target, key) {
|
||||
switch (key) {
|
||||
case 'webdriver':
|
||||
return undefined;
|
||||
case 'plugins':
|
||||
return [
|
||||
{ name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer' },
|
||||
{ name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai' },
|
||||
{ name: 'Native Client', filename: 'internal-nacl-plugin' }
|
||||
];
|
||||
case 'languages':
|
||||
return ['en-US', 'en'];
|
||||
default:
|
||||
return target[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Override permissions
|
||||
const originalPermissions = window.Permissions;
|
||||
window.Permissions = new Proxy(originalPermissions, {
|
||||
get: function(target, key) {
|
||||
if (key === 'prototype') {
|
||||
return {
|
||||
query: async () => ({ state: 'prompt' })
|
||||
};
|
||||
}
|
||||
return target[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Random canvas fingerprint
|
||||
const originalGetContext = HTMLCanvasElement.prototype.getContext;
|
||||
HTMLCanvasElement.prototype.getContext = function() {
|
||||
const context = originalGetContext.apply(this, arguments);
|
||||
if (context && arguments[0] === '2d') {
|
||||
const originalFillText = context.fillText;
|
||||
context.fillText = function() {
|
||||
const noise = Math.random() * 0.1;
|
||||
context.rotate(noise);
|
||||
originalFillText.apply(this, arguments);
|
||||
context.rotate(-noise);
|
||||
};
|
||||
}
|
||||
return context;
|
||||
};
|
||||
""")
|
||||
except:
|
||||
pass # Ignore if JavaScript execution fails
|
||||
|
||||
return config, page
|
||||
|
||||
except Exception as e:
|
||||
|
Loading…
x
Reference in New Issue
Block a user