| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785 |
- import tkinter as tk
- from tkinter import ttk, scrolledtext, messagebox, filedialog
- import requests
- import json
- import time
- import threading
- import re
- from datetime import datetime
- class GreenManGamingRegisterGUI:
- def __init__(self, root):
- self.root = root
- self.root.title("GreenManGaming 批量自动注册工具")
- self.root.geometry("900x880")
- self.root.resizable(False, False)
-
- # 存储session和token
- self.session = requests.Session()
- self.xsrf_token = None
- self.is_verifying = False
- self.success_accounts = [] # 存储成功注册的账号
- self.current_proxy = None
- self.proxy_last_update = 0 # 代理最后更新时间
- self.proxy_update_interval = 60 # 代理更新间隔(秒),默认60秒
- self.proxy_fail_count = 0 # 代理失败计数
-
- # 设置样式
- style = ttk.Style()
- style.configure("TLabel", font=("微软雅黑", 10))
- style.configure("TButton", font=("微软雅黑", 10))
- style.configure("TEntry", font=("微软雅黑", 10))
- # 主框架
- main_frame = ttk.Frame(root, padding="20 20 20 20")
- main_frame.pack(fill=tk.BOTH, expand=True)
- # 代理设置
- proxy_frame = ttk.LabelFrame(main_frame, text="代理设置", padding="10 10 10 10")
- proxy_frame.pack(fill=tk.X, pady=(0, 15))
-
- ttk.Label(proxy_frame, text="代理提取链接:").grid(row=0, column=0, sticky=tk.W, pady=5)
- self.proxy_url_var = tk.StringVar(value="")
- proxy_url_entry = ttk.Entry(proxy_frame, textvariable=self.proxy_url_var, width=50)
- proxy_url_entry.grid(row=0, column=1, sticky=tk.W, padx=(10, 0), pady=5)
-
- # 代理更换时间设置
- ttk.Label(proxy_frame, text="代理更换间隔(秒):").grid(row=1, column=0, sticky=tk.W, pady=5)
- self.proxy_interval_var = tk.StringVar(value="60")
- proxy_interval_entry = ttk.Entry(proxy_frame, textvariable=self.proxy_interval_var, width=10)
- proxy_interval_entry.grid(row=1, column=1, sticky=tk.W, padx=(10, 0), pady=5)
- ttk.Label(proxy_frame, text="(建议60-300秒,0表示每次注册都更换)", font=("微软雅黑", 8), foreground="gray").grid(row=1, column=2, padx=(10, 0))
-
- # 代理状态显示
- proxy_status_frame = ttk.Frame(proxy_frame)
- proxy_status_frame.grid(row=2, column=0, columnspan=3, sticky=tk.W, pady=(5, 0))
- self.proxy_status = ttk.Label(proxy_status_frame, text="代理状态: 未启用", font=("微软雅黑", 9), foreground="gray")
- self.proxy_status.pack(side=tk.LEFT)
-
- ttk.Label(proxy_frame, text="(留空则不使用代理,连接失败自动切换)", font=("微软雅黑", 8), foreground="gray").grid(row=3, column=1, sticky=tk.W, padx=(10, 0))
- # 临时邮箱API密钥
- mail_frame = ttk.LabelFrame(main_frame, text="临时邮箱设置", padding="10 10 10 10")
- mail_frame.pack(fill=tk.X, pady=(0, 15))
-
- ttk.Label(mail_frame, text="Sysq-Auth密钥:").grid(row=0, column=0, sticky=tk.W, pady=5)
- self.sysq_auth_var = tk.StringVar(value="ak-6c3b1eb026dff590bcb8b707365436a75ed15d7e9d0f674f2a38828847eb5286fa41d4aa3cb4c9ae07f27ebb7174f3dd")
- sysq_auth_entry = ttk.Entry(mail_frame, textvariable=self.sysq_auth_var, width=70)
- sysq_auth_entry.grid(row=0, column=1, sticky=tk.W, padx=(10, 0), pady=5)
- ttk.Label(mail_frame, text="(用于获取临时邮箱和验证码)", font=("微软雅黑", 8), foreground="gray").grid(row=1, column=1, sticky=tk.W, padx=(10, 0))
- # 注册参数
- input_frame = ttk.LabelFrame(main_frame, text="注册参数", padding="10 10 10 10")
- input_frame.pack(fill=tk.X, pady=(0, 15))
- # 密码
- ttk.Label(input_frame, text="密码:").grid(row=0, column=0, sticky=tk.W, pady=5)
- self.password_var = tk.StringVar(value="Test123456")
- password_entry = ttk.Entry(input_frame, textvariable=self.password_var, width=30)
- password_entry.grid(row=0, column=1, sticky=tk.W, padx=(10, 0), pady=5)
- ttk.Label(input_frame, text="(用户名和邮箱自动生成)", font=("微软雅黑", 8), foreground="gray").grid(row=0, column=2, padx=(10, 0))
- # 批量注册数量
- ttk.Label(input_frame, text="注册数量:").grid(row=1, column=0, sticky=tk.W, pady=5)
- self.count_var = tk.StringVar(value="1")
- count_entry = ttk.Entry(input_frame, textvariable=self.count_var, width=10)
- count_entry.grid(row=1, column=1, sticky=tk.W, padx=(10, 0), pady=5)
- ttk.Label(input_frame, text="(每次注册多个账号时,会依次注册)", font=("微软雅黑", 8), foreground="gray").grid(row=1, column=2, padx=(10, 0))
- # 邮件等待时间
- ttk.Label(input_frame, text="邮件等待时间(秒):").grid(row=2, column=0, sticky=tk.W, pady=5)
- self.wait_time_var = tk.StringVar(value="10")
- wait_time_entry = ttk.Entry(input_frame, textvariable=self.wait_time_var, width=10)
- wait_time_entry.grid(row=2, column=1, sticky=tk.W, padx=(10, 0), pady=5)
- ttk.Label(input_frame, text="(建议设置30-60秒等待邮件到达)", font=("微软雅黑", 8), foreground="gray").grid(row=2, column=2, padx=(10, 0))
- # 操作按钮
- button_frame = ttk.Frame(main_frame)
- button_frame.pack(fill=tk.X, pady=(0, 15))
- self.start_btn = ttk.Button(button_frame, text="开始批量注册", command=self.start_auto_register, width=18)
- self.start_btn.pack(side=tk.LEFT, padx=(0, 10))
-
- self.stop_btn = ttk.Button(button_frame, text="停止注册", command=self.stop_verification, width=15, state="disabled")
- self.stop_btn.pack(side=tk.LEFT, padx=(0, 10))
- clear_btn = ttk.Button(button_frame, text="清空日志", command=self.clear_log, width=15)
- clear_btn.pack(side=tk.LEFT, padx=(10, 0))
-
- copy_btn = ttk.Button(button_frame, text="复制成功账号", command=self.copy_success_accounts, width=15)
- copy_btn.pack(side=tk.LEFT, padx=(10, 0))
-
- export_btn = ttk.Button(button_frame, text="导出账号到TXT", command=self.export_accounts_to_txt, width=15)
- export_btn.pack(side=tk.LEFT, padx=(10, 0))
- # 成功账号列表
- success_frame = ttk.LabelFrame(main_frame, text="成功注册账号列表 (邮箱 | 密码)", padding="10 10 10 10")
- success_frame.pack(fill=tk.X, pady=(0, 15))
-
- # 列表和统计
- list_frame = ttk.Frame(success_frame)
- list_frame.pack(fill=tk.X)
-
- self.success_count_label = ttk.Label(list_frame, text="成功: 0 个", font=("微软雅黑", 9), foreground="green")
- self.success_count_label.pack(side=tk.LEFT)
-
- # 账号列表显示
- self.success_list_text = tk.Text(success_frame, height=4, font=("Consolas", 9), wrap=tk.WORD)
- self.success_list_text.pack(fill=tk.X, pady=(5, 0))
- self.success_list_text.config(state=tk.DISABLED)
- # 进度状态
- status_frame = ttk.LabelFrame(main_frame, text="执行状态", padding="10 10 10 10")
- status_frame.pack(fill=tk.X, pady=(0, 15))
- self.status_label = ttk.Label(status_frame, text="就绪", font=("微软雅黑", 10))
- self.status_label.pack(anchor=tk.W)
-
- # 进度条
- self.progress_var = tk.StringVar(value="0%")
- progress_frame = ttk.Frame(status_frame)
- progress_frame.pack(anchor=tk.W, pady=(5, 0))
- self.progress_label = ttk.Label(progress_frame, text="进度:", font=("微软雅黑", 9))
- self.progress_label.pack(side=tk.LEFT)
- self.progress_bar = ttk.Label(progress_frame, textvariable=self.progress_var, font=("微软雅黑", 9), foreground="blue")
- self.progress_bar.pack(side=tk.LEFT, padx=(5, 0))
- # 日志输出区域
- result_frame = ttk.LabelFrame(main_frame, text="日志输出", padding="10 10 10 10")
- result_frame.pack(fill=tk.BOTH, expand=True)
- self.result_text = scrolledtext.ScrolledText(
- result_frame,
- wrap=tk.WORD,
- font=("Consolas", 9),
- height=15
- )
- self.result_text.pack(fill=tk.BOTH, expand=True)
- # 配置文本标签颜色
- self.result_text.tag_config("timestamp", foreground="gray")
- self.result_text.tag_config("info", foreground="black")
- self.result_text.tag_config("success", foreground="green")
- self.result_text.tag_config("error", foreground="red")
- self.result_text.tag_config("warning", foreground="orange")
- self.result_text.tag_config("debug", foreground="purple")
- def log_message(self, message, level="INFO"):
- """添加日志消息"""
- timestamp = datetime.now().strftime("%H:%M:%S")
- tag_map = {
- "INFO": "info",
- "SUCCESS": "success",
- "ERROR": "error",
- "WARNING": "warning",
- "DEBUG": "debug"
- }
- tag = tag_map.get(level, "info")
-
- self.result_text.insert(tk.END, f"[{timestamp}] ", "timestamp")
- self.result_text.insert(tk.END, f"{message}\n", tag)
- self.result_text.see(tk.END)
- self.root.update()
- def update_progress(self, current, total, status=""):
- """更新进度"""
- if total > 0:
- percent = (current / total) * 100
- self.progress_var.set(f"{percent:.1f}%")
- self.status_label.config(text=status, foreground="blue")
- def add_success_account(self, email, password):
- """添加成功注册的账号到列表(只记录邮箱和密码)"""
- account_info = f"{email} | {password}"
- self.success_accounts.append(account_info)
-
- # 更新显示
- self.success_list_text.config(state=tk.NORMAL)
- self.success_list_text.insert(tk.END, account_info + "\n")
- self.success_list_text.see(tk.END)
- self.success_list_text.config(state=tk.DISABLED)
-
- # 更新计数
- self.success_count_label.config(text=f"成功: {len(self.success_accounts)} 个", foreground="green")
- def copy_success_accounts(self):
- """复制成功账号到剪贴板"""
- if not self.success_accounts:
- messagebox.showinfo("提示", "还没有成功注册的账号")
- return
-
- text = "\n".join(self.success_accounts)
- self.root.clipboard_clear()
- self.root.clipboard_append(text)
- self.root.update()
- messagebox.showinfo("成功", f"已复制 {len(self.success_accounts)} 个账号到剪贴板")
- def export_accounts_to_txt(self):
- """导出成功账号到TXT文件"""
- if not self.success_accounts:
- messagebox.showinfo("提示", "还没有成功注册的账号")
- return
-
- file_path = filedialog.asksaveasfilename(
- defaultextension=".txt",
- filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")],
- title="保存账号列表"
- )
-
- if not file_path:
- return
-
- try:
- with open(file_path, 'w', encoding='utf-8') as f:
- for account in self.success_accounts:
- f.write(account + '\n')
- messagebox.showinfo("成功", f"已成功导出 {len(self.success_accounts)} 个账号到:\n{file_path}")
- self.log_message(f"✓ 导出账号到: {file_path}", "SUCCESS")
- except Exception as e:
- messagebox.showerror("错误", f"导出失败: {str(e)}")
- self.log_message(f"✗ 导出失败: {str(e)}", "ERROR")
- def get_proxy(self):
- """从代理提取链接获取代理IP(根据设置的间隔更换)"""
- proxy_url = self.proxy_url_var.get().strip()
- if not proxy_url:
- self.proxy_status.config(text="代理状态: 未启用", foreground="gray")
- self.current_proxy = None
- return None
-
- # 获取代理更换间隔设置
- try:
- interval = int(self.proxy_interval_var.get().strip())
- if interval < 0:
- interval = 0
- self.proxy_update_interval = interval
- except:
- self.proxy_update_interval = 60
-
- # 检查是否需要更新代理
- current_time = time.time()
- time_since_update = current_time - self.proxy_last_update
-
- # 如果间隔为0,强制每次更换
- need_update = (self.proxy_update_interval == 0) or not self.current_proxy or (time_since_update >= self.proxy_update_interval) or (self.proxy_fail_count >= 3)
-
- if not need_update:
- self.log_message(f"使用现有代理(上次更新 {int(time_since_update)} 秒前,间隔 {self.proxy_update_interval} 秒)", "DEBUG")
- return self.current_proxy
-
- # 重置失败计数
- if self.proxy_fail_count >= 3:
- self.proxy_fail_count = 0
-
- try:
- self.log_message(f"正在获取新代理IP(上次更新 {int(time_since_update)} 秒前)...", "INFO")
- response = requests.get(proxy_url, timeout=10)
- response.raise_for_status()
-
- proxy_text = response.text.strip()
- if not proxy_text:
- self.log_message("✗ 代理提取链接返回空内容", "ERROR")
- self.proxy_status.config(text="代理状态: 获取失败", foreground="red")
- return None
-
- # 验证代理格式 (IP:PORT)
- if not re.match(r'^\d+\.\d+\.\d+\.\d+:\d+$', proxy_text):
- self.log_message(f"✗ 代理格式无效: {proxy_text}", "ERROR")
- self.proxy_status.config(text="代理状态: 格式无效", foreground="red")
- return None
-
- self.current_proxy = proxy_text
- self.proxy_last_update = current_time
- self.proxy_status.config(text=f"代理状态: {proxy_text} (间隔{self.proxy_update_interval}s)", foreground="green")
- self.log_message(f"✓ 获取代理成功: {proxy_text} (更换间隔: {self.proxy_update_interval}秒)", "SUCCESS")
- return proxy_text
-
- except Exception as e:
- self.log_message(f"✗ 获取代理失败: {str(e)}", "ERROR")
- self.proxy_status.config(text="代理状态: 获取失败", foreground="red")
- return None
- def get_session_with_proxy(self):
- """获取带代理的session"""
- session = requests.Session()
- if self.current_proxy:
- proxy_dict = {
- "http": f"http://{self.current_proxy}",
- "https": f"http://{self.current_proxy}"
- }
- session.proxies.update(proxy_dict)
- return session
- def fetch_token(self):
- """获取XSRF-TOKEN(注册时调用)"""
- self.log_message("正在获取XSRF-TOKEN...", "INFO")
-
- # 尝试最多3次获取Token
- for attempt in range(3):
- try:
- # 获取代理(如果启用)
- proxy_url = self.proxy_url_var.get().strip()
- if proxy_url:
- proxy = self.get_proxy()
- if not proxy:
- self.log_message("⚠ 获取代理失败,将使用直连", "WARNING")
- self.current_proxy = None
-
- # 创建带代理的session
- self.session = self.get_session_with_proxy()
-
- # 先访问首页获取初始Cookie
- self.session.get("https://www.greenmangaming.com/zh/", headers=self.get_base_headers(), timeout=30)
-
- # 请求用户信息接口
- url = "https://www.greenmangaming.com/api/v2/user_info"
- params = {
- "isFromCart": "false",
- "isFromPaymentPage": "false",
- "impactTrackingValue": ""
- }
-
- headers = self.get_base_headers()
- headers.update({
- "accept": "application/json",
- "current-url": "https://www.greenmangaming.com/zh/",
- "referer": "https://www.greenmangaming.com/zh/"
- })
-
- response = self.session.get(url, params=params, headers=headers, timeout=30)
- response.raise_for_status()
-
- # 从Cookie中提取XSRF-TOKEN
- self.xsrf_token = None
- for cookie in self.session.cookies:
- if cookie.name == "XSRF-TOKEN":
- self.xsrf_token = cookie.value
- break
-
- if self.xsrf_token:
- self.log_message(f"✓ XSRF-TOKEN获取成功: {self.xsrf_token[:30]}...", "SUCCESS")
- return True
- else:
- self.log_message("✗ 未找到XSRF-TOKEN", "ERROR")
- return False
-
- except requests.exceptions.ProxyError as e:
- self.log_message(f"✗ 代理连接失败 (尝试 {attempt+1}/3): {str(e)[:50]}", "ERROR")
- self.proxy_fail_count += 1
- self.proxy_status.config(text="代理状态: 连接失败,正在切换...", foreground="red")
-
- # 清除当前代理,强制获取新代理
- self.current_proxy = None
- self.proxy_last_update = 0
-
- if attempt < 2:
- self.log_message("正在尝试更换代理...", "INFO")
- time.sleep(2)
- else:
- self.log_message("✗ 代理连接失败次数过多,请检查代理设置", "ERROR")
- return False
-
- except Exception as e:
- self.log_message(f"✗ 获取Token失败: {str(e)}", "ERROR")
- return False
-
- return False
- def get_base_headers(self):
- """获取基础请求头"""
- return {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36",
- "Accept": "application/json, text/plain, */*",
- "Accept-Language": "zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5",
- "Gmg-Accept-Language": "zh",
- "X-Requested-With": "XMLHttpRequest",
- "Content-Type": "application/json;charset=utf-8",
- "withCredentials": "true",
- "Sec-Fetch-Dest": "empty",
- "Sec-Fetch-Mode": "cors",
- "Sec-Fetch-Site": "same-origin",
- }
- def get_temp_mail(self):
- """获取临时邮箱"""
- sysq_auth = self.sysq_auth_var.get().strip()
- if not sysq_auth:
- self.log_message("✗ 请设置Sysq-Auth密钥", "ERROR")
- return None
-
- try:
- self.log_message("正在从临时邮箱服务获取邮箱...", "INFO")
- url = "https://www.suiyongsuiqi.com/openapi/api/v1/mail/buy-random"
- headers = {
- "Accept": "*/*",
- "Content-Type": "application/json",
- "Sysq-Auth": sysq_auth,
- "User-Agent": "PostmanRuntime-ApipostRuntime/1.1.0"
- }
- data = {"suffix": "", "count": 1}
-
- response = requests.post(url, json=data, headers=headers, timeout=30)
- response.raise_for_status()
- result = response.json()
-
- if result.get("code") == 200 and result.get("data", {}).get("mailBoxes"):
- mailbox = result["data"]["mailBoxes"][0]
- return {
- "mailbox_id": mailbox["id"],
- "email": mailbox["fullAddress"],
- "username": mailbox["prefix"]
- }
- else:
- self.log_message(f"✗ 获取邮箱失败: {result.get('msg', '未知错误')}", "ERROR")
- return None
-
- except Exception as e:
- self.log_message(f"✗ 获取邮箱异常: {str(e)}", "ERROR")
- return None
- def send_register_request(self, username, email, password):
- """发送注册请求"""
- if not self.xsrf_token:
- self.log_message("✗ Token未就绪", "ERROR")
- return False
- self.log_message(f"正在注册用户: {username}", "INFO")
- payload = {
- "username": username,
- "email": email,
- "password": password,
- "confirmPassword": password,
- "isEmailFromExternal": False,
- "languagePreferenceCode": "zh",
- "isThirdPartyRegister": False,
- "currentLocationUrl": "/zh/",
- "radioCommunityEmailsOptIn": None,
- "radioMarketingEmailsOptIn": None,
- "hideBirthdayForm": False,
- "isExternalSignUp": False,
- "isPlayfireSignUp": False,
- "ReturnUrl": "/zh/",
- "newsletterOptIn": False,
- "termsAndConditions": True,
- "day": "01",
- "month": "02",
- "year": "1999",
- "Fingerprint": "OOGAlje8aAxW13m0ic0U"
- }
- headers = self.get_base_headers()
- headers.update({
- "X-XSRF-TOKEN": self.xsrf_token,
- "Current-Url": "https://www.greenmangaming.com/zh/",
- "Referer": "https://www.greenmangaming.com/zh/",
- "Origin": "https://www.greenmangaming.com"
- })
- try:
- url = "https://www.greenmangaming.com/api/v2/register"
- response = self.session.post(url, json=payload, headers=headers, timeout=30)
-
- if response.status_code == 200:
- self.log_message("✓ 注册请求发送成功,等待验证邮件...", "SUCCESS")
- return True
- else:
- self.log_message(f"✗ 注册失败 (状态码: {response.status_code})", "ERROR")
- try:
- error_data = response.json()
- self.log_message(f"错误信息: {json.dumps(error_data, ensure_ascii=False)[:200]}", "ERROR")
- except:
- self.log_message(f"响应内容: {response.text[:200]}", "ERROR")
- return False
-
- except requests.exceptions.ProxyError as e:
- self.log_message(f"✗ 代理连接错误: {str(e)[:50]}", "ERROR")
- self.proxy_fail_count += 1
- return False
- except Exception as e:
- self.log_message(f"✗ 注册请求异常: {str(e)}", "ERROR")
- return False
- def check_mail_for_code(self, mailbox_id):
- """检查邮件获取验证码"""
- if not mailbox_id:
- return None
-
- sysq_auth = self.sysq_auth_var.get().strip()
- if not sysq_auth:
- self.log_message("✗ 请设置Sysq-Auth密钥", "ERROR")
- return None
-
- try:
- url = "https://www.suiyongsuiqi.com/openapi/api/v1/mail/messages"
- headers = {
- "Accept": "*/*",
- "Content-Type": "application/json",
- "Sysq-Auth": sysq_auth,
- "User-Agent": "PostmanRuntime-ApipostRuntime/1.1.0"
- }
- data = {
- "mailBoxId": mailbox_id,
- "current": 1,
- "size": 20
- }
-
- response = requests.post(url, json=data, headers=headers, timeout=30)
- response.raise_for_status()
- result = response.json()
-
- if result.get("code") == 200:
- data = result.get("data", {})
- messages = data.get("messages", {})
- records = messages.get("records", [])
-
- if records and len(records) > 0:
- latest = records[0]
- content_html = latest.get("contentHtml", "")
-
- code_match = re.search(r'>\s*(\d{6})\s*<', content_html)
- if code_match:
- return code_match.group(1)
-
- code_match = re.search(r'\b(\d{6})\b', content_html)
- if code_match:
- return code_match.group(1)
-
- except Exception as e:
- self.log_message(f"检查邮件异常: {str(e)}", "WARNING")
-
- return None
- def get_verification_code(self, mailbox_id):
- """轮询获取验证码"""
- self.log_message("开始轮询获取验证码...", "INFO")
-
- try:
- wait_time = int(self.wait_time_var.get().strip())
- if wait_time > 0:
- self.log_message(f"等待 {wait_time} 秒让邮件到达...", "INFO")
-
- for i in range(wait_time):
- if not self.is_verifying:
- return None
- time.sleep(1)
- if i % 5 == 0 and i > 0:
- self.log_message(f"已等待 {i+1}/{wait_time} 秒...", "INFO")
- except ValueError:
- self.log_message("等待时间格式错误,使用默认30秒", "WARNING")
- time.sleep(30)
-
- max_attempts = 20
- attempt = 0
-
- while attempt < max_attempts and self.is_verifying:
- attempt += 1
- self.log_message(f"第 {attempt}/{max_attempts} 次检查邮件...", "INFO")
-
- code = self.check_mail_for_code(mailbox_id)
- if code:
- self.log_message(f"✓ 找到验证码: {code}", "SUCCESS")
- return code
-
- for i in range(3):
- if not self.is_verifying:
- return None
- time.sleep(1)
-
- self.log_message("✗ 获取验证码超时", "ERROR")
- return None
- def confirm_verification(self, code, email):
- """确认验证码"""
- if not code or not email or not self.xsrf_token:
- return False
-
- self.log_message(f"正在验证验证码: {code}", "INFO")
-
- try:
- url = "https://www.greenmangaming.com/api/v2/confirm_cognito_email_signup"
- params = {
- "confirmationCode": code,
- "email": email
- }
-
- headers = self.get_base_headers()
- headers.update({
- "X-XSRF-TOKEN": self.xsrf_token,
- "Current-Url": "https://www.greenmangaming.com/zh/",
- "Referer": "https://www.greenmangaming.com/zh/"
- })
-
- response = self.session.post(url, params=params, headers=headers, timeout=30)
-
- if response.status_code == 204:
- self.log_message("✓ 验证码确认成功!账号已激活!", "SUCCESS")
- return True
- elif response.status_code == 200:
- try:
- result = response.json()
- if result.get("success"):
- self.log_message("✓ 验证码确认成功!账号已激活!", "SUCCESS")
- return True
- except:
- pass
- self.log_message("✓ 验证码确认成功!账号已激活!", "SUCCESS")
- return True
- else:
- self.log_message(f"✗ 验证失败 (状态码: {response.status_code})", "ERROR")
- return False
-
- except requests.exceptions.ProxyError as e:
- self.log_message(f"✗ 代理连接错误: {str(e)[:50]}", "ERROR")
- self.proxy_fail_count += 1
- return False
- except Exception as e:
- self.log_message(f"✗ 验证请求异常: {str(e)}", "ERROR")
- return False
- def register_single_account(self, index, total):
- """注册单个账号"""
- self.log_message(f"\n{'='*50}", "INFO")
- self.log_message(f"开始注册第 {index}/{total} 个账号", "INFO")
-
- # 获取Token(每次注册都重新获取)
- if not self.fetch_token():
- self.log_message(f"✗ 第 {index} 个账号获取Token失败", "ERROR")
- return False
-
- # 获取邮箱
- mail_info = self.get_temp_mail()
- if not mail_info:
- self.log_message(f"✗ 第 {index} 个账号获取邮箱失败", "ERROR")
- return False
-
- username = mail_info["username"]
- email = mail_info["email"]
- mailbox_id = mail_info["mailbox_id"]
- password = self.password_var.get().strip()
-
- self.log_message(f"用户名: {username}", "INFO")
- self.log_message(f"邮箱: {email}", "INFO")
-
- # 发送注册请求
- if not self.send_register_request(username, email, password):
- self.log_message(f"✗ 第 {index} 个账号注册失败", "ERROR")
- return False
-
- # 获取验证码
- verification_code = self.get_verification_code(mailbox_id)
- if not verification_code:
- self.log_message(f"✗ 第 {index} 个账号获取验证码失败", "ERROR")
- return False
-
- # 确认验证
- if self.confirm_verification(verification_code, email):
- self.log_message(f"✓ 第 {index} 个账号注册成功!", "SUCCESS")
- self.add_success_account(email, password)
- return True
- else:
- self.log_message(f"✗ 第 {index} 个账号验证失败", "ERROR")
- return False
- def auto_register_flow(self):
- """批量自动注册流程"""
- self.is_verifying = True
- self.start_btn.config(state="disabled")
- self.stop_btn.config(state="normal")
-
- try:
- total_count = int(self.count_var.get().strip())
- if total_count < 1:
- total_count = 1
- except:
- total_count = 1
-
- self.log_message("="*60, "INFO")
- self.log_message(f"开始批量注册流程,共 {total_count} 个账号", "INFO")
- self.log_message("每个账号将使用独立的Token", "INFO")
-
- proxy_url = self.proxy_url_var.get().strip()
- if proxy_url:
- interval = self.proxy_interval_var.get().strip()
- self.log_message(f"代理模式已启用(代理更换间隔: {interval}秒,连接失败自动切换)", "INFO")
- else:
- self.log_message("直连模式(未使用代理)", "INFO")
-
- success_count = 0
-
- try:
- for i in range(1, total_count + 1):
- if not self.is_verifying:
- self.log_message("⚠ 用户停止了注册流程", "WARNING")
- break
-
- self.update_progress(i-1, total_count, f"正在注册第 {i}/{total_count} 个账号...")
-
- if self.register_single_account(i, total_count):
- success_count += 1
-
- if i < total_count and self.is_verifying:
- self.log_message("等待 3 秒后开始注册下一个账号...", "INFO")
- for _ in range(3):
- if not self.is_verifying:
- break
- time.sleep(1)
-
- self.log_message("="*60, "INFO")
- self.log_message(f"批量注册完成!成功: {success_count}/{total_count}", "SUCCESS" if success_count == total_count else "WARNING")
- self.status_label.config(text=f"注册完成!成功 {success_count}/{total_count}",
- foreground="green" if success_count == total_count else "orange")
- self.progress_var.set("100%")
-
- except Exception as e:
- self.log_message(f"✗ 批量注册流程异常: {str(e)}", "ERROR")
-
- finally:
- self.is_verifying = False
- self.start_btn.config(state="normal")
- self.stop_btn.config(state="disabled")
- def start_auto_register(self):
- """启动批量注册"""
- if not self.password_var.get().strip():
- messagebox.showerror("输入错误", "请设置密码")
- return
-
- if not self.sysq_auth_var.get().strip():
- messagebox.showerror("输入错误", "请设置Sysq-Auth密钥")
- return
-
- if self.success_accounts:
- if messagebox.askyesno("确认", f"已有 {len(self.success_accounts)} 个成功账号,是否清空列表?"):
- self.success_accounts.clear()
- self.success_list_text.config(state=tk.NORMAL)
- self.success_list_text.delete(1.0, tk.END)
- self.success_list_text.config(state=tk.DISABLED)
- self.success_count_label.config(text="成功: 0 个", foreground="green")
-
- # 重置代理状态
- self.current_proxy = None
- self.proxy_last_update = 0
- self.proxy_fail_count = 0
-
- thread = threading.Thread(target=self.auto_register_flow)
- thread.daemon = True
- thread.start()
- def stop_verification(self):
- """停止注册过程"""
- self.is_verifying = False
- self.log_message("⚠ 用户停止了注册流程", "WARNING")
- self.status_label.config(text="已停止", foreground="orange")
- self.start_btn.config(state="normal")
- self.stop_btn.config(state="disabled")
- def clear_log(self):
- """清空日志"""
- self.result_text.delete(1.0, tk.END)
- self.status_label.config(text="已清空日志", foreground="gray")
- if __name__ == "__main__":
- root = tk.Tk()
- app = GreenManGamingRegisterGUI(root)
- root.mainloop()
|