From 3fb99d17e08199d8020c915448330bb2ccc85b02 Mon Sep 17 00:00:00 2001 From: hkyc Date: Thu, 22 May 2025 22:43:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=82=AE=E7=AE=B1API?= =?UTF-8?q?=E9=9B=86=E6=88=90=E5=92=8C=E6=B3=A8=E5=86=8C=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E9=99=90=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EmailAPIClient.py | 84 +++++++ RegistrationGUIWithPynoV2.py | 212 ++++++++++++++---- ThreadManagerWithPyno.py | 110 +++++++-- .../SteamRegistrationWithPyno.cpython-312.pyc | Bin 44602 -> 45758 bytes start_pyno_v3.py | 12 +- 5 files changed, 348 insertions(+), 70 deletions(-) create mode 100644 EmailAPIClient.py diff --git a/EmailAPIClient.py b/EmailAPIClient.py new file mode 100644 index 0000000..9804029 --- /dev/null +++ b/EmailAPIClient.py @@ -0,0 +1,84 @@ +import requests +import json +from loguru import logger + +class EmailAPIClient: + """自建邮箱API客户端 + + 用于从API获取邮箱账号 + """ + + def __init__(self, api_url="https://steamapi.cursorpro.com.cn/api/create_user"): + """初始化API客户端 + + Args: + api_url: API服务器地址 + """ + self.api_url = api_url + + def create_email_account(self): + """创建新的邮箱账号 + + 通过调用API创建一个新的邮箱账号 + + Returns: + dict: 包含以下字段的字典,如果失败则返回None + - id: 账号ID + - username: 用户名 + - email: 邮箱地址 + - password: 邮箱密码 + - success: 是否成功 + - message: 信息 + """ + try: + logger.info(f"正在从API获取邮箱账号: {self.api_url}") + + response = requests.post(self.api_url, timeout=30) + + if response.status_code != 200: + logger.error(f"API请求失败,状态码: {response.status_code}") + return None + + try: + result = response.json() + except json.JSONDecodeError: + logger.error("API返回的数据不是有效的JSON格式") + return None + + if not result.get("success", False): + logger.error(f"API返回错误: {result.get('message', '未知错误')}") + return None + + logger.info(f"成功获取邮箱账号: {result.get('email')}") + return result + + except Exception as e: + logger.error(f"获取邮箱账号出错: {str(e)}") + return None + + def get_email_credentials(self): + """获取邮箱凭据 + + 获取邮箱地址和密码,并格式化为凭据字典 + + Returns: + dict: 包含email和password字段的字典,如果失败则返回None + """ + account = self.create_email_account() + if not account: + return None + + return { + 'email': account.get('email'), + 'password': account.get('password') + } + +# 测试代码 +if __name__ == "__main__": + client = EmailAPIClient() + email_data = client.get_email_credentials() + if email_data: + print(f"获取到的邮箱: {email_data['email']}") + print(f"获取到的密码: {email_data['password']}") + else: + print("获取邮箱账号失败") \ No newline at end of file diff --git a/RegistrationGUIWithPynoV2.py b/RegistrationGUIWithPynoV2.py index 4ee7adb..12f4aba 100644 --- a/RegistrationGUIWithPynoV2.py +++ b/RegistrationGUIWithPynoV2.py @@ -8,16 +8,17 @@ from tkinter import filedialog from ThreadManagerWithPyno import GUIThreadManagerWithPyno from PynoCaptchaSolver import PynoCaptchaConfig, PynoCaptchaSolver from SteamCaptchaHelper import SteamCaptchaHelper +from EmailAPIClient import EmailAPIClient import time # 配置日志 from loguru import logger -logger.add("steam_registration_pyno.log", rotation="10 MB") +logger.add("steam_registration.log", rotation="10 MB") -class RegistrationGUIWithPynoV2: +class SteamRegistrationGUI: def __init__(self, root): self.root = root - self.root.title("Steam注册 - PyNoCaptcha V2") + self.root.title("Steam账号注册助手") self.root.geometry("800x800") self.root.minsize(800, 800) # 设置最小窗口大小 @@ -30,7 +31,7 @@ class RegistrationGUIWithPynoV2: top_frame.pack(fill="x", side="top", padx=5, pady=5) # 创建配置框架 - config_frame = ttk.LabelFrame(top_frame, text="配置信息") + config_frame = ttk.LabelFrame(top_frame, text="基本配置") config_frame.pack(fill="x", padx=5, pady=5) # 加载默认配置 @@ -42,11 +43,11 @@ class RegistrationGUIWithPynoV2: self.config_vars = {} self._create_config_widgets(config_frame) - # 创建PyNoCaptcha配置框架 - captcha_frame = ttk.LabelFrame(top_frame, text="PyNoCaptcha配置") + # 创建验证码配置框架 + captcha_frame = ttk.LabelFrame(top_frame, text="验证码配置") captcha_frame.pack(fill="x", padx=5, pady=5) - # 创建PyNoCaptcha配置输入框 + # 创建验证码配置输入框 self.captcha_vars = {} self._create_captcha_widgets(captcha_frame) @@ -71,17 +72,51 @@ class RegistrationGUIWithPynoV2: ttk.Button(steam_frame, text="刷新验证信息", command=self._refresh_steam_info).grid(row=3, column=0, columnspan=2, padx=5, pady=5) + # 创建邮箱选项框架 + email_option_frame = ttk.LabelFrame(top_frame, text="邮箱设置") + email_option_frame.pack(fill="x", padx=5, pady=5) + + # 添加邮箱来源选择 + self.email_source_var = tk.StringVar(value="txt_file") + email_source_options = [ + ("自建邮箱API", "api"), + ("本地文件", "txt_file"), + ("微软Graph", "graph") + ] + + # 注册数量设置 + reg_count_frame = ttk.Frame(email_option_frame) + reg_count_frame.pack(fill="x", padx=5, pady=5) + + ttk.Label(reg_count_frame, text="注册数量:").grid(row=0, column=0, padx=5, pady=2, sticky="e") + self.reg_count_var = tk.StringVar(value="10") + ttk.Entry(reg_count_frame, textvariable=self.reg_count_var, width=10).grid(row=0, column=1, padx=5, pady=2, sticky="w") + ttk.Label(reg_count_frame, text="(0表示不限制)").grid(row=0, column=2, padx=5, pady=2, sticky="w") + + # 邮箱来源选择 + email_source_frame = ttk.Frame(email_option_frame) + email_source_frame.pack(fill="x", padx=5, pady=5) + + for i, (text, value) in enumerate(email_source_options): + ttk.Radiobutton( + email_source_frame, + text=text, + variable=self.email_source_var, + value=value, + command=self._toggle_email_source + ).grid(row=0, column=i, padx=10, pady=2) + # 创建文件选择框架 - files_frame = ttk.LabelFrame(top_frame, text="文件选择") - files_frame.pack(fill="x", padx=5, pady=5) + self.files_frame = ttk.LabelFrame(top_frame, text="文件选择") + self.files_frame.pack(fill="x", padx=5, pady=5) # 邮箱文件选择 self.email_path = tk.StringVar(value=os.path.join(self.script_dir, 'email_password.txt')) - self._create_file_selector(files_frame, "邮箱文件:", self.email_path, 0) + self._create_file_selector(self.files_frame, "邮箱文件:", self.email_path, 0) # 代理文件选择 self.proxy_path = tk.StringVar(value=os.path.join(self.script_dir, 'proxy_ips.txt')) - self._create_file_selector(files_frame, "代理文件:", self.proxy_path, 1) + self._create_file_selector(self.files_frame, "代理文件:", self.proxy_path, 1) # 按钮框架 - 直接放在主界面上,任务列表上方 button_frame = ttk.Frame(main_frame) @@ -92,7 +127,7 @@ class RegistrationGUIWithPynoV2: button_frame, text="开始注册", command=self.start_registration, - width=20 + width=15 ) self.start_button.pack(side="left", padx=10, pady=5, expand=True) @@ -102,7 +137,7 @@ class RegistrationGUIWithPynoV2: text="停止注册", command=self.stop_registration, state="disabled", - width=20 + width=15 ) self.stop_button.pack(side="left", padx=10, pady=5, expand=True) @@ -111,10 +146,19 @@ class RegistrationGUIWithPynoV2: button_frame, text="测试验证码", command=self.test_captcha, - width=20 + width=15 ) self.test_captcha_button.pack(side="left", padx=10, pady=5, expand=True) + # 添加获取邮箱测试按钮 + self.test_email_button = ttk.Button( + button_frame, + text="测试邮箱API", + command=self.test_email_api, + width=15 + ) + self.test_email_button.pack(side="left", padx=10, pady=5, expand=True) + # 中间框架 - 包含任务状态表格 middle_frame = ttk.Frame(main_frame) middle_frame.pack(fill="both", expand=True, padx=5, pady=5) @@ -162,9 +206,31 @@ class RegistrationGUIWithPynoV2: self._stop_progress_update = False # 添加版本标签 - version_label = ttk.Label(main_frame, text="PyNoCaptcha V2 版本", foreground="blue") + version_label = ttk.Label(main_frame, text="Steam账号注册助手 V3.0", foreground="blue") version_label.pack(side="bottom", padx=5, pady=5) + + # 初始化邮箱API客户端 + self.email_api_client = EmailAPIClient() + + # 初始设置邮箱来源 + self._toggle_email_source() + def _toggle_email_source(self): + """根据邮箱来源选择切换界面显示""" + source = self.email_source_var.get() + + # 首先隐藏所有与邮箱相关的文件选择框 + for widget in self.files_frame.winfo_children(): + if "邮箱文件" in str(widget): + widget.grid_remove() + + # 根据所选邮箱来源显示相应控件 + if source == "txt_file": + # 显示邮箱文件选择框 + for widget in self.files_frame.winfo_children(): + if "邮箱文件" in str(widget): + widget.grid() + def _refresh_steam_info(self): """刷新Steam验证信息""" threading.Thread(target=self._refresh_steam_info_thread, daemon=True).start() @@ -209,11 +275,11 @@ class RegistrationGUIWithPynoV2: ] for i, (key, label, options) in enumerate(config_items): - ttk.Label(parent, text=label,width=10).grid(row=i, column=0, padx=5, pady=2, sticky="e") + ttk.Label(parent, text=label, width=10).grid(row=i, column=0, padx=5, pady=2, sticky="e") if options: var = tk.StringVar(value=str(self.config.get(key, ""))) - widget = ttk.Combobox(parent, textvariable=var, values=options,width=50) + widget = ttk.Combobox(parent, textvariable=var, values=options, width=50) else: var = tk.StringVar(value=str(self.config.get(key, ""))) widget = ttk.Entry(parent, textvariable=var, width=50) @@ -222,22 +288,22 @@ class RegistrationGUIWithPynoV2: self.config_vars[key] = var def _create_captcha_widgets(self, parent): - """创建PyNoCaptcha配置输入控件""" + """创建验证码配置输入控件""" captcha_items = [ - ("pyno_user_token", "PyNoCaptcha API密钥:", None), - ("pyno_sitekey", "验证码网站Key:", None), - ("pyno_referer", "网站Referer:", None), + ("pyno_user_token", "API密钥:", None), + ("pyno_sitekey", "网站Key:", None), + ("pyno_referer", "Referer:", None), ("pyno_user_agent", "User-Agent:", None), ("pyno_timeout", "超时时间(秒):", None), ("pyno_debug", "调试模式:", ["True", "False"]) ] for i, (key, label, options) in enumerate(captcha_items): - ttk.Label(parent, text=label,width=12).grid(row=i, column=0, padx=5, pady=2, sticky="e") + ttk.Label(parent, text=label, width=10).grid(row=i, column=0, padx=5, pady=2, sticky="e") if options: var = tk.StringVar(value=str(self.config.get(key, "True" if key == "pyno_debug" else "False"))) - widget = ttk.Combobox(parent, textvariable=var, values=options,width=50) + widget = ttk.Combobox(parent, textvariable=var, values=options, width=50) else: default_value = "" if key == "pyno_sitekey": @@ -334,7 +400,7 @@ class RegistrationGUIWithPynoV2: value = value.lower() == "true" config[key] = value - # 保存PyNoCaptcha配置 + # 保存验证码配置 for key, var in self.captcha_vars.items(): value = var.get() if key == "pyno_timeout": @@ -343,6 +409,10 @@ class RegistrationGUIWithPynoV2: value = value.lower() == "true" config[key] = value + # 保存邮箱来源配置 + config['email_source'] = self.email_source_var.get() + config['reg_count'] = int(self.reg_count_var.get()) + with open(self.config_path, 'w') as f: json.dump(config, f, indent=2) return True @@ -352,7 +422,9 @@ class RegistrationGUIWithPynoV2: def _validate_inputs(self): """验证输入""" - if not os.path.exists(self.email_path.get()): + # 检查邮箱来源 + email_source = self.email_source_var.get() + if email_source == "txt_file" and not os.path.exists(self.email_path.get()): messagebox.showerror("错误", "邮箱文件不存在") return False @@ -366,17 +438,27 @@ class RegistrationGUIWithPynoV2: messagebox.showerror("错误", f"请填写 {key} 配置项") return False - # 验证PyNoCaptcha配置 + # 验证验证码配置 required_captcha_keys = ["pyno_user_token"] for key in required_captcha_keys: if not self.captcha_vars[key].get().strip(): messagebox.showerror("错误", f"请填写 {key} 配置项") return False + # 验证注册数量 + try: + count = int(self.reg_count_var.get()) + if count < 0: + messagebox.showerror("错误", "注册数量不能为负数") + return False + except ValueError: + messagebox.showerror("错误", "注册数量必须是整数") + return False + return True def get_captcha_config(self): - """获取PyNoCaptcha配置""" + """获取验证码配置""" return PynoCaptchaConfig( user_token=self.captcha_vars["pyno_user_token"].get(), sitekey=self.captcha_vars["pyno_sitekey"].get(), @@ -386,11 +468,52 @@ class RegistrationGUIWithPynoV2: debug=self.captcha_vars["pyno_debug"].get().lower() == "true" ) + def test_email_api(self): + """测试邮箱API功能""" + # 禁用测试按钮 + self.test_email_button.config(state="disabled") + + # 在新线程中测试 + threading.Thread(target=self._test_email_api_thread, daemon=True).start() + + def _test_email_api_thread(self): + """在新线程中测试邮箱API""" + try: + test_id = "测试邮箱API" + self.update_status(test_id, status="正在从API获取邮箱...") + + # 获取邮箱账号 + email_data = self.email_api_client.get_email_credentials() + + if not email_data: + self.update_status(test_id, status="获取邮箱失败", result="失败") + messagebox.showerror("错误", "无法从API获取邮箱账号") + return + + # 显示结果 + self.update_status( + test_id, + status=f"获取邮箱成功: {email_data['email']}", + account_name="N/A", + password=email_data['password'], + result="成功" + ) + + messagebox.showinfo("成功", f"成功获取邮箱: {email_data['email']}") + + except Exception as e: + logger.error(f"测试邮箱API出错: {str(e)}") + messagebox.showerror("错误", f"测试过程中出错: {str(e)}") + self.update_status(test_id, status=f"出错: {str(e)}", result="错误") + finally: + # 恢复按钮状态 + self.test_email_button.config(state="normal") + def test_captcha(self): - """测试PyNoCaptcha验证码""" + """测试验证码""" # 验证配置 if not self.captcha_vars["pyno_user_token"].get().strip(): - messagebox.showerror("错误", "请先填写PyNoCaptcha API密钥") + messagebox.showerror("错误", "请先填写验证码API密钥") return # 保存配置 @@ -404,9 +527,9 @@ class RegistrationGUIWithPynoV2: threading.Thread(target=self._test_captcha_thread, daemon=True).start() def _test_captcha_thread(self): - """在新线程中测试PyNoCaptcha""" + """在新线程中测试验证码""" try: - test_id = "测试PyNoCaptcha" + test_id = "测试验证码" self.update_status(test_id, status="正在准备验证码测试...") # 首先获取动态sitekey @@ -481,7 +604,7 @@ class RegistrationGUIWithPynoV2: except Exception as e: logger.error(f"测试过程中出错: {str(e)}") messagebox.showerror("错误", f"测试过程中出错: {str(e)}") - self.update_status("测试PyNoCaptcha", status=f"出错: {str(e)}", result="错误") + self.update_status("测试验证码", status=f"出错: {str(e)}", result="错误") finally: # 恢复按钮状态 self.test_captcha_button.config(state="normal") @@ -547,17 +670,24 @@ class RegistrationGUIWithPynoV2: messagebox.showerror("错误", f"获取Steam验证信息失败: {str(e)}") return - # 使用PyNoCaptcha版本的GUIThreadManager - self.manager = GUIThreadManagerWithPyno( - self.config_path, - self.email_path.get(), - self.proxy_path.get(), - self, - completed_tasks - ) + # 创建参数字典 + manager_params = { + 'config_path': self.config_path, + 'email_path': self.email_path.get(), + 'proxy_path': self.proxy_path.get(), + 'gui': self, + 'completed_tasks': completed_tasks, + 'email_source': self.email_source_var.get(), + 'reg_count': int(self.reg_count_var.get()), + 'email_api_client': self.email_api_client if self.email_source_var.get() == "api" else None + } + + # 使用线程管理器 + self.manager = GUIThreadManagerWithPyno(**manager_params) self.manager.start() except Exception as e: + logger.error(f"启动注册线程出错: {str(e)}") messagebox.showerror("错误", str(e)) finally: self.start_button.config(state="normal") @@ -572,7 +702,7 @@ class RegistrationGUIWithPynoV2: if __name__ == "__main__": root = tk.Tk() - gui = RegistrationGUIWithPynoV2(root) + gui = SteamRegistrationGUI(root) # 启动时自动刷新Steam信息 threading.Thread(target=gui._refresh_steam_info_thread, daemon=True).start() root.mainloop() \ No newline at end of file diff --git a/ThreadManagerWithPyno.py b/ThreadManagerWithPyno.py index 48ae094..3519a7e 100644 --- a/ThreadManagerWithPyno.py +++ b/ThreadManagerWithPyno.py @@ -4,11 +4,12 @@ import os import threading from ProxyPool import ProxyPool from SteamRegistrationWithPyno import SteamRegistrationWithPyno +from EmailAPIClient import EmailAPIClient class ThreadManagerWithPyno: - """线程管理器 - 使用PyNoCaptcha版本""" - def __init__(self, config_path, email_file_path, proxy_file_path): + """线程管理器 - 使用验证码解决方案""" + def __init__(self, config_path, email_file_path, proxy_file_path, email_source="txt_file", reg_count=0, email_api_client=None): self.config = self._load_config(config_path) self._validate_config() self.proxy_pool = ProxyPool(proxy_file_path) @@ -18,6 +19,11 @@ class ThreadManagerWithPyno: self._running = True self._registrations = set() self._registrations_lock = threading.Lock() + self.email_source = email_source + self.reg_count = reg_count + self.processed_count = 0 + self.count_lock = threading.Lock() + self.email_api_client = email_api_client or EmailAPIClient() def _validate_config(self): """验证配置有效性""" @@ -62,10 +68,28 @@ class ThreadManagerWithPyno: return self._registration_local.registration def process_email(self, email_data): + """处理一个邮箱账号的注册""" + # 检查是否达到注册数量限制 + if self.reg_count > 0: + with self.count_lock: + if self.processed_count >= self.reg_count: + print(f"已达到注册数量限制: {self.reg_count}") + return + self.processed_count += 1 + registration = self._get_registration() registration.main(email_data) - + def get_email_from_api(self): + """从API获取邮箱账号""" + try: + email_data = self.email_api_client.get_email_credentials() + if email_data: + return email_data + except Exception as e: + print(f"从API获取邮箱失败: {e}") + return None + def stop(self): """停止所有任务""" self._running = False @@ -92,28 +116,47 @@ class ThreadManagerWithPyno: """启动处理""" self._running = True try: - with open(self.email_file, "r") as file: - for line in file: - if not self._running: + if self.email_source == "api": + # 使用API获取邮箱 + while self._running and (self.reg_count == 0 or self.processed_count < self.reg_count): + email_data = self.get_email_from_api() + if not email_data: + print("无法从API获取邮箱,任务停止") break - try: - email_data = self.parse_email_credentials(line.strip()) - self.executor.submit(self.process_email, email_data) - except ValueError as e: - print(f"错误的邮箱格式: {e}") - continue + self.executor.submit(self.process_email, email_data) + else: + # 使用本地文件获取邮箱 + with open(self.email_file, "r", encoding="utf-8") as file: + for line in file: + if not self._running or (self.reg_count > 0 and self.processed_count >= self.reg_count): + break + try: + email_data = self.parse_email_credentials(line.strip()) + self.executor.submit(self.process_email, email_data) + except ValueError as e: + print(f"错误的邮箱格式: {e}") + continue finally: self.executor.shutdown(wait=True) class GUIThreadManagerWithPyno(ThreadManagerWithPyno): - def __init__(self, config_path, email_file_path, proxy_file_path, gui, completed_tasks=None): - super().__init__(config_path, email_file_path, proxy_file_path) + def __init__(self, config_path, email_path, proxy_path, gui, completed_tasks=None, email_source="txt_file", reg_count=0, email_api_client=None): + super().__init__(config_path, email_path, proxy_path, email_source, reg_count, email_api_client) self.gui = gui self.completed_tasks = completed_tasks or set() def process_email(self, email_data): """处理单个邮件账号""" try: + # 检查是否达到注册数量限制 + if self.reg_count > 0: + with self.count_lock: + if self.processed_count >= self.reg_count: + print(f"已达到注册数量限制: {self.reg_count}") + return + self.processed_count += 1 + print(f"当前处理数量: {self.processed_count}/{self.reg_count}") + if not self._running: # 检查是否应该继续 self.gui.update_status(email_data['email'], "任务已停止") return @@ -141,15 +184,36 @@ class GUIThreadManagerWithPyno(ThreadManagerWithPyno): def start(self): """启动处理""" self._running = True - with open(self.email_file, 'r', encoding='utf-8') as file: - with ThreadPoolExecutor(max_workers=self.config['executornum']) as self.executor: - for line in file: - if not self._running: - break - try: - email_data = self.parse_email_credentials(line) + self.processed_count = 0 # 重置计数器 + + try: + if self.email_source == "api": + # 使用API获取邮箱 + with ThreadPoolExecutor(max_workers=self.config['executornum']) as self.executor: + while self._running and (self.reg_count == 0 or self.processed_count < self.reg_count): + email_data = self.get_email_from_api() + if not email_data: + self.gui.update_status("API错误", "无法从API获取邮箱", result="失败") + break + # 跳过已完成的任务 if email_data['email'] not in self.completed_tasks: self.executor.submit(self.process_email, email_data) - except ValueError as e: - self.gui.update_status(email_data['email'],f"解析邮箱文件失败: {e}") \ No newline at end of file + else: + print(f"跳过已完成的邮箱: {email_data['email']}") + else: + # 使用本地文件获取邮箱 + with open(self.email_file, 'r', encoding='utf-8') as file: + with ThreadPoolExecutor(max_workers=self.config['executornum']) as self.executor: + for line in file: + if not self._running or (self.reg_count > 0 and self.processed_count >= self.reg_count): + break + try: + email_data = self.parse_email_credentials(line) + # 跳过已完成的任务 + if email_data['email'] not in self.completed_tasks: + self.executor.submit(self.process_email, email_data) + except ValueError as e: + self.gui.update_status("解析错误", f"解析邮箱文件失败: {e}") + except Exception as e: + self.gui.update_status("系统错误", f"启动任务失败: {str(e)}", result="失败") \ No newline at end of file diff --git a/__pycache__/SteamRegistrationWithPyno.cpython-312.pyc b/__pycache__/SteamRegistrationWithPyno.cpython-312.pyc index c5ddd57c641741c1315a45dfb44ae97517c9da8c..bdfaf6c5c9f96e3e805437d06f87fcc70ccac137 100644 GIT binary patch delta 2818 zcmbtVdrVu`8NcV+*B3vqdDy%Sl&1-pS76Wp?W}@%w7l6Ukj-^J3;VmAwGlB%_eYc!6)hdan2_3bFi6=V{a zgtN>wk{=(1lw0f)TSDP8y-Eqr7Q&YZd9sAx43zMjq5g`z`3+N;-wdCWT?4-4fHEn` z8E6Dh){L*cm9Qso#U;YcUF->mufHTa_*Ay1vma9?Q+bpf4AFpUqX0g~GNC**LO&Ki zENG*KKr-bB^R-4%DHIpwmN--a+oW>g2QW!LZoUn-@0J{wjFtIT7*ZQ6R{An!M8JaD z-chFvU;g>x;^$|6xV?DxZy&$o48cUApPBo?7gHw*NnUW`m#=>C#Rm)6YqUz&do=^9Z}J8JAe9cI*JS?_XsyPW8#+uL;< znMZdh@J+gKqwv}5h6Te?ySK0b6*Qv8?i~S0>je|y2O=s>bEWlS>y^V756`Du&soSp zFSLF(n)>pDCv;dD+$Di!Do)X=itVDL5= z(D%B%4Lzv77xfNoWarP>W^9WVZ+11()~uzhIc|^M8bt<+x4sY6^`rj5K#0woU5B*w zYupY)XE%cf6s>Lndje`Sz5*b1`HqCr6#V};xuuMHyJoy*;@BN!#$EyyQM$)aa`hR* zo|5v_dAJvfS)?j?^dON^s&^^))B5<)R6gjT-H2b#&w*YexGC2Q>E&SE!HQz$Q%VKgmN3PP9*9@USj?{q#rjlcHCV1sWL9GtoM|@|!&kL~o&16+%ug7Hrv!f@XzfMpH82Oq+|hH9-ipjEffK|=V$B{T_5%&chN&|qAQ zUzaBZDyd207r)d6d0Y0B9T*)xzsw}}`xTQx@Slybbcp}DK%P+Ejy47Igz@t)e3EsG ztZ8^i`Kmk_9rfR$T>@X5K!od*fnhQZH2cPZGH{RlIA9%-0o$Z>vC!BQE@h9icmPmt zyz&Ep@(%zNoNju)eMI5YoSEZn9FZh1ZtfgT!;6{Y$j(mSJO-y2!{b4~;6dq|7+=11 z{?BuB+i$$LePN1>2oZq)YSMrEJ#t|_0SkdX3>iUO1zt8qoY`o%SvMtoXNVw>>9*~b4Sl!ATi1(f zEy!Zs(B{n82GJmgM@6;+OLG*cokW}QFM^#QN|QIQyq>U- zuoUUdt46sssHPot7}h&1-VO`ub9y_DqV}O3iW&x0G+wIdda_i}4PR$^(1RR76=o=W^0CQrA4(lVTRBN*_Ilfxl`=wkG%`-icq@ zvJB`m1`s0I+cVI>Z0rx#6 zrW-W)hv%!V3Lz+mrG3q`i1v*4?E-KBo*K}EWa5v(_w^niJ1zWpU<4$2imbm00+moW zbV>6(`Hon-^N7XV>EQUNED}ooU$`RvA_C>`w?l7$bkBE&&j}AzVg`S*hlzt!*pykF z1BL;!-EQnQ+qolzHxpj$Fb_KnM{K5JoR*MPQ0wM^!!zZcrB$(nNg&WmYSj^_gvJxE zsj3OtO~A?n@f?PaPLzf0YlwKNVAaVaQ9Ry`6hU2I5%{a;>d8McAO?<|j#BF}zbWkM zwVHU5@p8*xd8Ki7xO}=$G)S(@g5S@Kg^_1M!AG8qGd~joHQXA@2FRm$eOj0uL+X^1 z4hjgQ5Ev#9M;s$$M-=R9KNxO}*Mn0q_ss&Z>oLCx6{2(;=1hiX3so@u(h2V@q5E=-h$VT(;N;~d5boKztYuSz3B#u+nK<(JIPxSo zHGxwE-hsN=*CbI)@os^V$=}U_Xtq|WA)deRMWE*Wd2j{(?)@gka4^W+r3i9W*!OQ1 CyiElF delta 1842 zcmb7EdrVVj6u;kXZ+ly43(^-LL0c%TCio+Y878K256yu@n0J~x3HM1$QiNpc1+xXwr64?YhAohzolVR%h6qwLU0*G?T z$?r0aSHjOf{WEesl}~w54~?i+97ojfmR>o4!-wXD?C{ z^ko!hNUc*ozz(v*`SEuT>Y;k!=N7d@9&cw#f{KO{iQFiz;0_Qt1Uni}A_-h*d;uB^ zTA&Y>p?s(~m>)=x?R}t19WzZHp4;=Cs${{ptVzGnKhi&09M$CU1=gs>x@;_*9Gq)j zFfOEp3U3MTDQ+wHm)fHH+xc1>Z*wghc1(MwJae5Rm&l?M+>o2g>9DLyX)a(Ex3kz;EMUwf zlEpn@VwX!SnM_11x1=!<6@&95X$)a91;o}dmRzx8W5BU-5GBTxXQyGL>3iDjhj5x& zx+ynl%q1$LH%u(EO|zkyW#w2$LbvYUs>JdM;egODfc!}ntjH7K&E{liZ_(xaEgWTR z9~ff7VSJiR9}9z1!iOwH!&| z8>=p`Y}$1-b2f896E#)x#^(fLi`Lrt8VBz?a>+=Uv1~@PCnZ; zCS8szByFs3Nx5TPL8;6Bl1M49Dt-1O2?|^FR@H_?>hMX!iO7;I2+QRbM2ELlvF0LX zF^k2{Vi995mn;^Gu^mAYi;js%<(3R4qGfPFBm+x@iRc8x&SormVg~}gRvCQIIw(L4 zymE9MiVtho| z#4>)c%yRl)iGOU7a{0I|2*-sy7qxL8&WN%fE!7Q~7O?1Lu%yC^;QqkmLb zT!k4E%UMZ)tZ+Zk-F>RFgF_v`tg}~W zm6|YV1Wu5(8VFRuqql}s7DC!%5dv-!u|i;|Ea|xok%$@Y4(U)T{618Q9tL;5{S$*! zkTk4Cm0%i9M{cMdE)sR&%)XuQT5dXA98N}8gP#t6E);1AYa*<|fpzI~wb>jFPq*6_ z3Bt(7!aNn}Zy_re638OZOF%;ceZ=Y_5Zkr{oTH5*{PCvxcE=W48daiSf-9q-Ksp%s zfVCr*|O*pqUiZ0;(B688ADu zRTRG{xHD6P-T^e5CSu4I&cXKCCL|8}W_O9RB!p2A$RLnPfSj8n$K=SyxcA}fxglvX svvQk;~b+%<|Iw;#v;1kNEA*8l(j diff --git a/start_pyno_v3.py b/start_pyno_v3.py index f7ef8c0..8f02957 100644 --- a/start_pyno_v3.py +++ b/start_pyno_v3.py @@ -2,16 +2,16 @@ # -*- coding: utf-8 -*- """ -Steam注册程序 - PyNoCaptcha V3版本启动器 -使用PyNoCaptcha解决验证码,解决了sitekey获取问题 +Steam注册程序 - V3版本启动器 +支持API获取邮箱账号和注册数量限制功能 """ import tkinter as tk -from RegistrationGUIWithPynoV2 import RegistrationGUIWithPynoV2 +from RegistrationGUIWithPynoV2 import SteamRegistrationGUI if __name__ == "__main__": - print("正在启动Steam注册助手 PyNoCaptcha V3版本...") - print("这个版本修复了验证码头信息问题,使用正确的User-Agent获取sitekey") + print("正在启动Steam账号注册助手 V3.0...") + print("这个版本新增自建邮箱API获取功能和注册数量限制功能") root = tk.Tk() - gui = RegistrationGUIWithPynoV2(root) + gui = SteamRegistrationGUI(root) root.mainloop() \ No newline at end of file