自动注册.py 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. import tkinter as tk
  2. from tkinter import ttk, scrolledtext, messagebox, filedialog
  3. import requests
  4. import json
  5. import time
  6. import threading
  7. import re
  8. from datetime import datetime
  9. class GreenManGamingRegisterGUI:
  10. def __init__(self, root):
  11. self.root = root
  12. self.root.title("GreenManGaming 批量自动注册工具")
  13. self.root.geometry("900x880")
  14. self.root.resizable(False, False)
  15. # 存储session和token
  16. self.session = requests.Session()
  17. self.xsrf_token = None
  18. self.is_verifying = False
  19. self.success_accounts = [] # 存储成功注册的账号
  20. self.current_proxy = None
  21. self.proxy_last_update = 0 # 代理最后更新时间
  22. self.proxy_update_interval = 60 # 代理更新间隔(秒),默认60秒
  23. self.proxy_fail_count = 0 # 代理失败计数
  24. # 设置样式
  25. style = ttk.Style()
  26. style.configure("TLabel", font=("微软雅黑", 10))
  27. style.configure("TButton", font=("微软雅黑", 10))
  28. style.configure("TEntry", font=("微软雅黑", 10))
  29. # 主框架
  30. main_frame = ttk.Frame(root, padding="20 20 20 20")
  31. main_frame.pack(fill=tk.BOTH, expand=True)
  32. # 代理设置
  33. proxy_frame = ttk.LabelFrame(main_frame, text="代理设置", padding="10 10 10 10")
  34. proxy_frame.pack(fill=tk.X, pady=(0, 15))
  35. ttk.Label(proxy_frame, text="代理提取链接:").grid(row=0, column=0, sticky=tk.W, pady=5)
  36. self.proxy_url_var = tk.StringVar(value="")
  37. proxy_url_entry = ttk.Entry(proxy_frame, textvariable=self.proxy_url_var, width=50)
  38. proxy_url_entry.grid(row=0, column=1, sticky=tk.W, padx=(10, 0), pady=5)
  39. # 代理更换时间设置
  40. ttk.Label(proxy_frame, text="代理更换间隔(秒):").grid(row=1, column=0, sticky=tk.W, pady=5)
  41. self.proxy_interval_var = tk.StringVar(value="60")
  42. proxy_interval_entry = ttk.Entry(proxy_frame, textvariable=self.proxy_interval_var, width=10)
  43. proxy_interval_entry.grid(row=1, column=1, sticky=tk.W, padx=(10, 0), pady=5)
  44. ttk.Label(proxy_frame, text="(建议60-300秒,0表示每次注册都更换)", font=("微软雅黑", 8), foreground="gray").grid(row=1, column=2, padx=(10, 0))
  45. # 代理状态显示
  46. proxy_status_frame = ttk.Frame(proxy_frame)
  47. proxy_status_frame.grid(row=2, column=0, columnspan=3, sticky=tk.W, pady=(5, 0))
  48. self.proxy_status = ttk.Label(proxy_status_frame, text="代理状态: 未启用", font=("微软雅黑", 9), foreground="gray")
  49. self.proxy_status.pack(side=tk.LEFT)
  50. ttk.Label(proxy_frame, text="(留空则不使用代理,连接失败自动切换)", font=("微软雅黑", 8), foreground="gray").grid(row=3, column=1, sticky=tk.W, padx=(10, 0))
  51. # 临时邮箱API密钥
  52. mail_frame = ttk.LabelFrame(main_frame, text="临时邮箱设置", padding="10 10 10 10")
  53. mail_frame.pack(fill=tk.X, pady=(0, 15))
  54. ttk.Label(mail_frame, text="Sysq-Auth密钥:").grid(row=0, column=0, sticky=tk.W, pady=5)
  55. self.sysq_auth_var = tk.StringVar(value="ak-6c3b1eb026dff590bcb8b707365436a75ed15d7e9d0f674f2a38828847eb5286fa41d4aa3cb4c9ae07f27ebb7174f3dd")
  56. sysq_auth_entry = ttk.Entry(mail_frame, textvariable=self.sysq_auth_var, width=70)
  57. sysq_auth_entry.grid(row=0, column=1, sticky=tk.W, padx=(10, 0), pady=5)
  58. ttk.Label(mail_frame, text="(用于获取临时邮箱和验证码)", font=("微软雅黑", 8), foreground="gray").grid(row=1, column=1, sticky=tk.W, padx=(10, 0))
  59. # 注册参数
  60. input_frame = ttk.LabelFrame(main_frame, text="注册参数", padding="10 10 10 10")
  61. input_frame.pack(fill=tk.X, pady=(0, 15))
  62. # 密码
  63. ttk.Label(input_frame, text="密码:").grid(row=0, column=0, sticky=tk.W, pady=5)
  64. self.password_var = tk.StringVar(value="Test123456")
  65. password_entry = ttk.Entry(input_frame, textvariable=self.password_var, width=30)
  66. password_entry.grid(row=0, column=1, sticky=tk.W, padx=(10, 0), pady=5)
  67. ttk.Label(input_frame, text="(用户名和邮箱自动生成)", font=("微软雅黑", 8), foreground="gray").grid(row=0, column=2, padx=(10, 0))
  68. # 批量注册数量
  69. ttk.Label(input_frame, text="注册数量:").grid(row=1, column=0, sticky=tk.W, pady=5)
  70. self.count_var = tk.StringVar(value="1")
  71. count_entry = ttk.Entry(input_frame, textvariable=self.count_var, width=10)
  72. count_entry.grid(row=1, column=1, sticky=tk.W, padx=(10, 0), pady=5)
  73. ttk.Label(input_frame, text="(每次注册多个账号时,会依次注册)", font=("微软雅黑", 8), foreground="gray").grid(row=1, column=2, padx=(10, 0))
  74. # 邮件等待时间
  75. ttk.Label(input_frame, text="邮件等待时间(秒):").grid(row=2, column=0, sticky=tk.W, pady=5)
  76. self.wait_time_var = tk.StringVar(value="10")
  77. wait_time_entry = ttk.Entry(input_frame, textvariable=self.wait_time_var, width=10)
  78. wait_time_entry.grid(row=2, column=1, sticky=tk.W, padx=(10, 0), pady=5)
  79. ttk.Label(input_frame, text="(建议设置30-60秒等待邮件到达)", font=("微软雅黑", 8), foreground="gray").grid(row=2, column=2, padx=(10, 0))
  80. # 操作按钮
  81. button_frame = ttk.Frame(main_frame)
  82. button_frame.pack(fill=tk.X, pady=(0, 15))
  83. self.start_btn = ttk.Button(button_frame, text="开始批量注册", command=self.start_auto_register, width=18)
  84. self.start_btn.pack(side=tk.LEFT, padx=(0, 10))
  85. self.stop_btn = ttk.Button(button_frame, text="停止注册", command=self.stop_verification, width=15, state="disabled")
  86. self.stop_btn.pack(side=tk.LEFT, padx=(0, 10))
  87. clear_btn = ttk.Button(button_frame, text="清空日志", command=self.clear_log, width=15)
  88. clear_btn.pack(side=tk.LEFT, padx=(10, 0))
  89. copy_btn = ttk.Button(button_frame, text="复制成功账号", command=self.copy_success_accounts, width=15)
  90. copy_btn.pack(side=tk.LEFT, padx=(10, 0))
  91. export_btn = ttk.Button(button_frame, text="导出账号到TXT", command=self.export_accounts_to_txt, width=15)
  92. export_btn.pack(side=tk.LEFT, padx=(10, 0))
  93. # 成功账号列表
  94. success_frame = ttk.LabelFrame(main_frame, text="成功注册账号列表 (邮箱 | 密码)", padding="10 10 10 10")
  95. success_frame.pack(fill=tk.X, pady=(0, 15))
  96. # 列表和统计
  97. list_frame = ttk.Frame(success_frame)
  98. list_frame.pack(fill=tk.X)
  99. self.success_count_label = ttk.Label(list_frame, text="成功: 0 个", font=("微软雅黑", 9), foreground="green")
  100. self.success_count_label.pack(side=tk.LEFT)
  101. # 账号列表显示
  102. self.success_list_text = tk.Text(success_frame, height=4, font=("Consolas", 9), wrap=tk.WORD)
  103. self.success_list_text.pack(fill=tk.X, pady=(5, 0))
  104. self.success_list_text.config(state=tk.DISABLED)
  105. # 进度状态
  106. status_frame = ttk.LabelFrame(main_frame, text="执行状态", padding="10 10 10 10")
  107. status_frame.pack(fill=tk.X, pady=(0, 15))
  108. self.status_label = ttk.Label(status_frame, text="就绪", font=("微软雅黑", 10))
  109. self.status_label.pack(anchor=tk.W)
  110. # 进度条
  111. self.progress_var = tk.StringVar(value="0%")
  112. progress_frame = ttk.Frame(status_frame)
  113. progress_frame.pack(anchor=tk.W, pady=(5, 0))
  114. self.progress_label = ttk.Label(progress_frame, text="进度:", font=("微软雅黑", 9))
  115. self.progress_label.pack(side=tk.LEFT)
  116. self.progress_bar = ttk.Label(progress_frame, textvariable=self.progress_var, font=("微软雅黑", 9), foreground="blue")
  117. self.progress_bar.pack(side=tk.LEFT, padx=(5, 0))
  118. # 日志输出区域
  119. result_frame = ttk.LabelFrame(main_frame, text="日志输出", padding="10 10 10 10")
  120. result_frame.pack(fill=tk.BOTH, expand=True)
  121. self.result_text = scrolledtext.ScrolledText(
  122. result_frame,
  123. wrap=tk.WORD,
  124. font=("Consolas", 9),
  125. height=15
  126. )
  127. self.result_text.pack(fill=tk.BOTH, expand=True)
  128. # 配置文本标签颜色
  129. self.result_text.tag_config("timestamp", foreground="gray")
  130. self.result_text.tag_config("info", foreground="black")
  131. self.result_text.tag_config("success", foreground="green")
  132. self.result_text.tag_config("error", foreground="red")
  133. self.result_text.tag_config("warning", foreground="orange")
  134. self.result_text.tag_config("debug", foreground="purple")
  135. def log_message(self, message, level="INFO"):
  136. """添加日志消息"""
  137. timestamp = datetime.now().strftime("%H:%M:%S")
  138. tag_map = {
  139. "INFO": "info",
  140. "SUCCESS": "success",
  141. "ERROR": "error",
  142. "WARNING": "warning",
  143. "DEBUG": "debug"
  144. }
  145. tag = tag_map.get(level, "info")
  146. self.result_text.insert(tk.END, f"[{timestamp}] ", "timestamp")
  147. self.result_text.insert(tk.END, f"{message}\n", tag)
  148. self.result_text.see(tk.END)
  149. self.root.update()
  150. def update_progress(self, current, total, status=""):
  151. """更新进度"""
  152. if total > 0:
  153. percent = (current / total) * 100
  154. self.progress_var.set(f"{percent:.1f}%")
  155. self.status_label.config(text=status, foreground="blue")
  156. def add_success_account(self, email, password):
  157. """添加成功注册的账号到列表(只记录邮箱和密码)"""
  158. account_info = f"{email} | {password}"
  159. self.success_accounts.append(account_info)
  160. # 更新显示
  161. self.success_list_text.config(state=tk.NORMAL)
  162. self.success_list_text.insert(tk.END, account_info + "\n")
  163. self.success_list_text.see(tk.END)
  164. self.success_list_text.config(state=tk.DISABLED)
  165. # 更新计数
  166. self.success_count_label.config(text=f"成功: {len(self.success_accounts)} 个", foreground="green")
  167. def copy_success_accounts(self):
  168. """复制成功账号到剪贴板"""
  169. if not self.success_accounts:
  170. messagebox.showinfo("提示", "还没有成功注册的账号")
  171. return
  172. text = "\n".join(self.success_accounts)
  173. self.root.clipboard_clear()
  174. self.root.clipboard_append(text)
  175. self.root.update()
  176. messagebox.showinfo("成功", f"已复制 {len(self.success_accounts)} 个账号到剪贴板")
  177. def export_accounts_to_txt(self):
  178. """导出成功账号到TXT文件"""
  179. if not self.success_accounts:
  180. messagebox.showinfo("提示", "还没有成功注册的账号")
  181. return
  182. file_path = filedialog.asksaveasfilename(
  183. defaultextension=".txt",
  184. filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")],
  185. title="保存账号列表"
  186. )
  187. if not file_path:
  188. return
  189. try:
  190. with open(file_path, 'w', encoding='utf-8') as f:
  191. for account in self.success_accounts:
  192. f.write(account + '\n')
  193. messagebox.showinfo("成功", f"已成功导出 {len(self.success_accounts)} 个账号到:\n{file_path}")
  194. self.log_message(f"✓ 导出账号到: {file_path}", "SUCCESS")
  195. except Exception as e:
  196. messagebox.showerror("错误", f"导出失败: {str(e)}")
  197. self.log_message(f"✗ 导出失败: {str(e)}", "ERROR")
  198. def get_proxy(self):
  199. """从代理提取链接获取代理IP(根据设置的间隔更换)"""
  200. proxy_url = self.proxy_url_var.get().strip()
  201. if not proxy_url:
  202. self.proxy_status.config(text="代理状态: 未启用", foreground="gray")
  203. self.current_proxy = None
  204. return None
  205. # 获取代理更换间隔设置
  206. try:
  207. interval = int(self.proxy_interval_var.get().strip())
  208. if interval < 0:
  209. interval = 0
  210. self.proxy_update_interval = interval
  211. except:
  212. self.proxy_update_interval = 60
  213. # 检查是否需要更新代理
  214. current_time = time.time()
  215. time_since_update = current_time - self.proxy_last_update
  216. # 如果间隔为0,强制每次更换
  217. 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)
  218. if not need_update:
  219. self.log_message(f"使用现有代理(上次更新 {int(time_since_update)} 秒前,间隔 {self.proxy_update_interval} 秒)", "DEBUG")
  220. return self.current_proxy
  221. # 重置失败计数
  222. if self.proxy_fail_count >= 3:
  223. self.proxy_fail_count = 0
  224. try:
  225. self.log_message(f"正在获取新代理IP(上次更新 {int(time_since_update)} 秒前)...", "INFO")
  226. response = requests.get(proxy_url, timeout=10)
  227. response.raise_for_status()
  228. proxy_text = response.text.strip()
  229. if not proxy_text:
  230. self.log_message("✗ 代理提取链接返回空内容", "ERROR")
  231. self.proxy_status.config(text="代理状态: 获取失败", foreground="red")
  232. return None
  233. # 验证代理格式 (IP:PORT)
  234. if not re.match(r'^\d+\.\d+\.\d+\.\d+:\d+$', proxy_text):
  235. self.log_message(f"✗ 代理格式无效: {proxy_text}", "ERROR")
  236. self.proxy_status.config(text="代理状态: 格式无效", foreground="red")
  237. return None
  238. self.current_proxy = proxy_text
  239. self.proxy_last_update = current_time
  240. self.proxy_status.config(text=f"代理状态: {proxy_text} (间隔{self.proxy_update_interval}s)", foreground="green")
  241. self.log_message(f"✓ 获取代理成功: {proxy_text} (更换间隔: {self.proxy_update_interval}秒)", "SUCCESS")
  242. return proxy_text
  243. except Exception as e:
  244. self.log_message(f"✗ 获取代理失败: {str(e)}", "ERROR")
  245. self.proxy_status.config(text="代理状态: 获取失败", foreground="red")
  246. return None
  247. def get_session_with_proxy(self):
  248. """获取带代理的session"""
  249. session = requests.Session()
  250. if self.current_proxy:
  251. proxy_dict = {
  252. "http": f"http://{self.current_proxy}",
  253. "https": f"http://{self.current_proxy}"
  254. }
  255. session.proxies.update(proxy_dict)
  256. return session
  257. def fetch_token(self):
  258. """获取XSRF-TOKEN(注册时调用)"""
  259. self.log_message("正在获取XSRF-TOKEN...", "INFO")
  260. # 尝试最多3次获取Token
  261. for attempt in range(3):
  262. try:
  263. # 获取代理(如果启用)
  264. proxy_url = self.proxy_url_var.get().strip()
  265. if proxy_url:
  266. proxy = self.get_proxy()
  267. if not proxy:
  268. self.log_message("⚠ 获取代理失败,将使用直连", "WARNING")
  269. self.current_proxy = None
  270. # 创建带代理的session
  271. self.session = self.get_session_with_proxy()
  272. # 先访问首页获取初始Cookie
  273. self.session.get("https://www.greenmangaming.com/zh/", headers=self.get_base_headers(), timeout=30)
  274. # 请求用户信息接口
  275. url = "https://www.greenmangaming.com/api/v2/user_info"
  276. params = {
  277. "isFromCart": "false",
  278. "isFromPaymentPage": "false",
  279. "impactTrackingValue": ""
  280. }
  281. headers = self.get_base_headers()
  282. headers.update({
  283. "accept": "application/json",
  284. "current-url": "https://www.greenmangaming.com/zh/",
  285. "referer": "https://www.greenmangaming.com/zh/"
  286. })
  287. response = self.session.get(url, params=params, headers=headers, timeout=30)
  288. response.raise_for_status()
  289. # 从Cookie中提取XSRF-TOKEN
  290. self.xsrf_token = None
  291. for cookie in self.session.cookies:
  292. if cookie.name == "XSRF-TOKEN":
  293. self.xsrf_token = cookie.value
  294. break
  295. if self.xsrf_token:
  296. self.log_message(f"✓ XSRF-TOKEN获取成功: {self.xsrf_token[:30]}...", "SUCCESS")
  297. return True
  298. else:
  299. self.log_message("✗ 未找到XSRF-TOKEN", "ERROR")
  300. return False
  301. except requests.exceptions.ProxyError as e:
  302. self.log_message(f"✗ 代理连接失败 (尝试 {attempt+1}/3): {str(e)[:50]}", "ERROR")
  303. self.proxy_fail_count += 1
  304. self.proxy_status.config(text="代理状态: 连接失败,正在切换...", foreground="red")
  305. # 清除当前代理,强制获取新代理
  306. self.current_proxy = None
  307. self.proxy_last_update = 0
  308. if attempt < 2:
  309. self.log_message("正在尝试更换代理...", "INFO")
  310. time.sleep(2)
  311. else:
  312. self.log_message("✗ 代理连接失败次数过多,请检查代理设置", "ERROR")
  313. return False
  314. except Exception as e:
  315. self.log_message(f"✗ 获取Token失败: {str(e)}", "ERROR")
  316. return False
  317. return False
  318. def get_base_headers(self):
  319. """获取基础请求头"""
  320. return {
  321. "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",
  322. "Accept": "application/json, text/plain, */*",
  323. "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",
  324. "Gmg-Accept-Language": "zh",
  325. "X-Requested-With": "XMLHttpRequest",
  326. "Content-Type": "application/json;charset=utf-8",
  327. "withCredentials": "true",
  328. "Sec-Fetch-Dest": "empty",
  329. "Sec-Fetch-Mode": "cors",
  330. "Sec-Fetch-Site": "same-origin",
  331. }
  332. def get_temp_mail(self):
  333. """获取临时邮箱"""
  334. sysq_auth = self.sysq_auth_var.get().strip()
  335. if not sysq_auth:
  336. self.log_message("✗ 请设置Sysq-Auth密钥", "ERROR")
  337. return None
  338. try:
  339. self.log_message("正在从临时邮箱服务获取邮箱...", "INFO")
  340. url = "https://www.suiyongsuiqi.com/openapi/api/v1/mail/buy-random"
  341. headers = {
  342. "Accept": "*/*",
  343. "Content-Type": "application/json",
  344. "Sysq-Auth": sysq_auth,
  345. "User-Agent": "PostmanRuntime-ApipostRuntime/1.1.0"
  346. }
  347. data = {"suffix": "", "count": 1}
  348. response = requests.post(url, json=data, headers=headers, timeout=30)
  349. response.raise_for_status()
  350. result = response.json()
  351. if result.get("code") == 200 and result.get("data", {}).get("mailBoxes"):
  352. mailbox = result["data"]["mailBoxes"][0]
  353. return {
  354. "mailbox_id": mailbox["id"],
  355. "email": mailbox["fullAddress"],
  356. "username": mailbox["prefix"]
  357. }
  358. else:
  359. self.log_message(f"✗ 获取邮箱失败: {result.get('msg', '未知错误')}", "ERROR")
  360. return None
  361. except Exception as e:
  362. self.log_message(f"✗ 获取邮箱异常: {str(e)}", "ERROR")
  363. return None
  364. def send_register_request(self, username, email, password):
  365. """发送注册请求"""
  366. if not self.xsrf_token:
  367. self.log_message("✗ Token未就绪", "ERROR")
  368. return False
  369. self.log_message(f"正在注册用户: {username}", "INFO")
  370. payload = {
  371. "username": username,
  372. "email": email,
  373. "password": password,
  374. "confirmPassword": password,
  375. "isEmailFromExternal": False,
  376. "languagePreferenceCode": "zh",
  377. "isThirdPartyRegister": False,
  378. "currentLocationUrl": "/zh/",
  379. "radioCommunityEmailsOptIn": None,
  380. "radioMarketingEmailsOptIn": None,
  381. "hideBirthdayForm": False,
  382. "isExternalSignUp": False,
  383. "isPlayfireSignUp": False,
  384. "ReturnUrl": "/zh/",
  385. "newsletterOptIn": False,
  386. "termsAndConditions": True,
  387. "day": "01",
  388. "month": "02",
  389. "year": "1999",
  390. "Fingerprint": "OOGAlje8aAxW13m0ic0U"
  391. }
  392. headers = self.get_base_headers()
  393. headers.update({
  394. "X-XSRF-TOKEN": self.xsrf_token,
  395. "Current-Url": "https://www.greenmangaming.com/zh/",
  396. "Referer": "https://www.greenmangaming.com/zh/",
  397. "Origin": "https://www.greenmangaming.com"
  398. })
  399. try:
  400. url = "https://www.greenmangaming.com/api/v2/register"
  401. response = self.session.post(url, json=payload, headers=headers, timeout=30)
  402. if response.status_code == 200:
  403. self.log_message("✓ 注册请求发送成功,等待验证邮件...", "SUCCESS")
  404. return True
  405. else:
  406. self.log_message(f"✗ 注册失败 (状态码: {response.status_code})", "ERROR")
  407. try:
  408. error_data = response.json()
  409. self.log_message(f"错误信息: {json.dumps(error_data, ensure_ascii=False)[:200]}", "ERROR")
  410. except:
  411. self.log_message(f"响应内容: {response.text[:200]}", "ERROR")
  412. return False
  413. except requests.exceptions.ProxyError as e:
  414. self.log_message(f"✗ 代理连接错误: {str(e)[:50]}", "ERROR")
  415. self.proxy_fail_count += 1
  416. return False
  417. except Exception as e:
  418. self.log_message(f"✗ 注册请求异常: {str(e)}", "ERROR")
  419. return False
  420. def check_mail_for_code(self, mailbox_id):
  421. """检查邮件获取验证码"""
  422. if not mailbox_id:
  423. return None
  424. sysq_auth = self.sysq_auth_var.get().strip()
  425. if not sysq_auth:
  426. self.log_message("✗ 请设置Sysq-Auth密钥", "ERROR")
  427. return None
  428. try:
  429. url = "https://www.suiyongsuiqi.com/openapi/api/v1/mail/messages"
  430. headers = {
  431. "Accept": "*/*",
  432. "Content-Type": "application/json",
  433. "Sysq-Auth": sysq_auth,
  434. "User-Agent": "PostmanRuntime-ApipostRuntime/1.1.0"
  435. }
  436. data = {
  437. "mailBoxId": mailbox_id,
  438. "current": 1,
  439. "size": 20
  440. }
  441. response = requests.post(url, json=data, headers=headers, timeout=30)
  442. response.raise_for_status()
  443. result = response.json()
  444. if result.get("code") == 200:
  445. data = result.get("data", {})
  446. messages = data.get("messages", {})
  447. records = messages.get("records", [])
  448. if records and len(records) > 0:
  449. latest = records[0]
  450. content_html = latest.get("contentHtml", "")
  451. code_match = re.search(r'>\s*(\d{6})\s*<', content_html)
  452. if code_match:
  453. return code_match.group(1)
  454. code_match = re.search(r'\b(\d{6})\b', content_html)
  455. if code_match:
  456. return code_match.group(1)
  457. except Exception as e:
  458. self.log_message(f"检查邮件异常: {str(e)}", "WARNING")
  459. return None
  460. def get_verification_code(self, mailbox_id):
  461. """轮询获取验证码"""
  462. self.log_message("开始轮询获取验证码...", "INFO")
  463. try:
  464. wait_time = int(self.wait_time_var.get().strip())
  465. if wait_time > 0:
  466. self.log_message(f"等待 {wait_time} 秒让邮件到达...", "INFO")
  467. for i in range(wait_time):
  468. if not self.is_verifying:
  469. return None
  470. time.sleep(1)
  471. if i % 5 == 0 and i > 0:
  472. self.log_message(f"已等待 {i+1}/{wait_time} 秒...", "INFO")
  473. except ValueError:
  474. self.log_message("等待时间格式错误,使用默认30秒", "WARNING")
  475. time.sleep(30)
  476. max_attempts = 20
  477. attempt = 0
  478. while attempt < max_attempts and self.is_verifying:
  479. attempt += 1
  480. self.log_message(f"第 {attempt}/{max_attempts} 次检查邮件...", "INFO")
  481. code = self.check_mail_for_code(mailbox_id)
  482. if code:
  483. self.log_message(f"✓ 找到验证码: {code}", "SUCCESS")
  484. return code
  485. for i in range(3):
  486. if not self.is_verifying:
  487. return None
  488. time.sleep(1)
  489. self.log_message("✗ 获取验证码超时", "ERROR")
  490. return None
  491. def confirm_verification(self, code, email):
  492. """确认验证码"""
  493. if not code or not email or not self.xsrf_token:
  494. return False
  495. self.log_message(f"正在验证验证码: {code}", "INFO")
  496. try:
  497. url = "https://www.greenmangaming.com/api/v2/confirm_cognito_email_signup"
  498. params = {
  499. "confirmationCode": code,
  500. "email": email
  501. }
  502. headers = self.get_base_headers()
  503. headers.update({
  504. "X-XSRF-TOKEN": self.xsrf_token,
  505. "Current-Url": "https://www.greenmangaming.com/zh/",
  506. "Referer": "https://www.greenmangaming.com/zh/"
  507. })
  508. response = self.session.post(url, params=params, headers=headers, timeout=30)
  509. if response.status_code == 204:
  510. self.log_message("✓ 验证码确认成功!账号已激活!", "SUCCESS")
  511. return True
  512. elif response.status_code == 200:
  513. try:
  514. result = response.json()
  515. if result.get("success"):
  516. self.log_message("✓ 验证码确认成功!账号已激活!", "SUCCESS")
  517. return True
  518. except:
  519. pass
  520. self.log_message("✓ 验证码确认成功!账号已激活!", "SUCCESS")
  521. return True
  522. else:
  523. self.log_message(f"✗ 验证失败 (状态码: {response.status_code})", "ERROR")
  524. return False
  525. except requests.exceptions.ProxyError as e:
  526. self.log_message(f"✗ 代理连接错误: {str(e)[:50]}", "ERROR")
  527. self.proxy_fail_count += 1
  528. return False
  529. except Exception as e:
  530. self.log_message(f"✗ 验证请求异常: {str(e)}", "ERROR")
  531. return False
  532. def register_single_account(self, index, total):
  533. """注册单个账号"""
  534. self.log_message(f"\n{'='*50}", "INFO")
  535. self.log_message(f"开始注册第 {index}/{total} 个账号", "INFO")
  536. # 获取Token(每次注册都重新获取)
  537. if not self.fetch_token():
  538. self.log_message(f"✗ 第 {index} 个账号获取Token失败", "ERROR")
  539. return False
  540. # 获取邮箱
  541. mail_info = self.get_temp_mail()
  542. if not mail_info:
  543. self.log_message(f"✗ 第 {index} 个账号获取邮箱失败", "ERROR")
  544. return False
  545. username = mail_info["username"]
  546. email = mail_info["email"]
  547. mailbox_id = mail_info["mailbox_id"]
  548. password = self.password_var.get().strip()
  549. self.log_message(f"用户名: {username}", "INFO")
  550. self.log_message(f"邮箱: {email}", "INFO")
  551. # 发送注册请求
  552. if not self.send_register_request(username, email, password):
  553. self.log_message(f"✗ 第 {index} 个账号注册失败", "ERROR")
  554. return False
  555. # 获取验证码
  556. verification_code = self.get_verification_code(mailbox_id)
  557. if not verification_code:
  558. self.log_message(f"✗ 第 {index} 个账号获取验证码失败", "ERROR")
  559. return False
  560. # 确认验证
  561. if self.confirm_verification(verification_code, email):
  562. self.log_message(f"✓ 第 {index} 个账号注册成功!", "SUCCESS")
  563. self.add_success_account(email, password)
  564. return True
  565. else:
  566. self.log_message(f"✗ 第 {index} 个账号验证失败", "ERROR")
  567. return False
  568. def auto_register_flow(self):
  569. """批量自动注册流程"""
  570. self.is_verifying = True
  571. self.start_btn.config(state="disabled")
  572. self.stop_btn.config(state="normal")
  573. try:
  574. total_count = int(self.count_var.get().strip())
  575. if total_count < 1:
  576. total_count = 1
  577. except:
  578. total_count = 1
  579. self.log_message("="*60, "INFO")
  580. self.log_message(f"开始批量注册流程,共 {total_count} 个账号", "INFO")
  581. self.log_message("每个账号将使用独立的Token", "INFO")
  582. proxy_url = self.proxy_url_var.get().strip()
  583. if proxy_url:
  584. interval = self.proxy_interval_var.get().strip()
  585. self.log_message(f"代理模式已启用(代理更换间隔: {interval}秒,连接失败自动切换)", "INFO")
  586. else:
  587. self.log_message("直连模式(未使用代理)", "INFO")
  588. success_count = 0
  589. try:
  590. for i in range(1, total_count + 1):
  591. if not self.is_verifying:
  592. self.log_message("⚠ 用户停止了注册流程", "WARNING")
  593. break
  594. self.update_progress(i-1, total_count, f"正在注册第 {i}/{total_count} 个账号...")
  595. if self.register_single_account(i, total_count):
  596. success_count += 1
  597. if i < total_count and self.is_verifying:
  598. self.log_message("等待 3 秒后开始注册下一个账号...", "INFO")
  599. for _ in range(3):
  600. if not self.is_verifying:
  601. break
  602. time.sleep(1)
  603. self.log_message("="*60, "INFO")
  604. self.log_message(f"批量注册完成!成功: {success_count}/{total_count}", "SUCCESS" if success_count == total_count else "WARNING")
  605. self.status_label.config(text=f"注册完成!成功 {success_count}/{total_count}",
  606. foreground="green" if success_count == total_count else "orange")
  607. self.progress_var.set("100%")
  608. except Exception as e:
  609. self.log_message(f"✗ 批量注册流程异常: {str(e)}", "ERROR")
  610. finally:
  611. self.is_verifying = False
  612. self.start_btn.config(state="normal")
  613. self.stop_btn.config(state="disabled")
  614. def start_auto_register(self):
  615. """启动批量注册"""
  616. if not self.password_var.get().strip():
  617. messagebox.showerror("输入错误", "请设置密码")
  618. return
  619. if not self.sysq_auth_var.get().strip():
  620. messagebox.showerror("输入错误", "请设置Sysq-Auth密钥")
  621. return
  622. if self.success_accounts:
  623. if messagebox.askyesno("确认", f"已有 {len(self.success_accounts)} 个成功账号,是否清空列表?"):
  624. self.success_accounts.clear()
  625. self.success_list_text.config(state=tk.NORMAL)
  626. self.success_list_text.delete(1.0, tk.END)
  627. self.success_list_text.config(state=tk.DISABLED)
  628. self.success_count_label.config(text="成功: 0 个", foreground="green")
  629. # 重置代理状态
  630. self.current_proxy = None
  631. self.proxy_last_update = 0
  632. self.proxy_fail_count = 0
  633. thread = threading.Thread(target=self.auto_register_flow)
  634. thread.daemon = True
  635. thread.start()
  636. def stop_verification(self):
  637. """停止注册过程"""
  638. self.is_verifying = False
  639. self.log_message("⚠ 用户停止了注册流程", "WARNING")
  640. self.status_label.config(text="已停止", foreground="orange")
  641. self.start_btn.config(state="normal")
  642. self.stop_btn.config(state="disabled")
  643. def clear_log(self):
  644. """清空日志"""
  645. self.result_text.delete(1.0, tk.END)
  646. self.status_label.config(text="已清空日志", foreground="gray")
  647. if __name__ == "__main__":
  648. root = tk.Tk()
  649. app = GreenManGamingRegisterGUI(root)
  650. root.mainloop()