Просмотр исходного кода

Merge branch 'main' of https://git.port.run/puge/pythonTest

PUGE 3 недель назад
Родитель
Сommit
0c3a046799
1 измененных файлов с 228 добавлено и 0 удалено
  1. 228 0
      自动购买.py

+ 228 - 0
自动购买.py

@@ -0,0 +1,228 @@
+import tkinter as tk
+from tkinter import ttk, scrolledtext, messagebox
+from datetime import datetime
+import threading
+import requests
+
+
+# ========== 固定配置 ==========
+BASE_URL = "http://task.port.run"   # 服务器地址(固定)
+CHANNEL = "自动注册"                 # 频道
+TIMEOUT = "6000"                      # 任务超时秒数
+
+
+class NewToolGUI:
+    def __init__(self, root):
+        self.root = root
+        self.root.title("新工具 - 批量购买平台")
+        self.root.geometry("900x850")
+        self.root.resizable(False, False)
+
+        self.running = False
+
+        # 样式
+        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)
+
+        # ========== 账号列表 ==========
+        account_frame = ttk.LabelFrame(main_frame, text="账号列表 (每行一个账号,格式:邮箱 | 密码)", padding="10 10 10 10")
+        account_frame.pack(fill=tk.X, pady=(0, 15))
+
+        self.account_list_text = tk.Text(account_frame, height=6, font=("Consolas", 9), wrap=tk.WORD)
+        self.account_list_text.pack(fill=tk.X)
+        self.account_list_text.insert(tk.END, "example1@mail.com | password123\n")
+        self.account_list_text.insert(tk.END, "example2@mail.com | password456\n")
+
+        # ========== 购买参数 ==========
+        purchase_frame = ttk.LabelFrame(main_frame, text="购买参数", padding="10 10 10 10")
+        purchase_frame.pack(fill=tk.X, pady=(0, 15))
+
+        ttk.Label(purchase_frame, text="游戏购买地址:").grid(row=0, column=0, sticky=tk.W, pady=5)
+        self.game_url_var = tk.StringVar(value="")
+        game_url_entry = ttk.Entry(purchase_frame, textvariable=self.game_url_var, width=60)
+        game_url_entry.grid(row=0, column=1, columnspan=2, sticky=tk.W, padx=(10, 0), pady=5)
+
+        ttk.Label(purchase_frame, text="购买数量:").grid(row=1, column=0, sticky=tk.W, pady=5)
+        self.quantity_var = tk.StringVar(value="1")
+        quantity_entry = ttk.Entry(purchase_frame, textvariable=self.quantity_var, width=10)
+        quantity_entry.grid(row=1, column=1, sticky=tk.W, padx=(10, 0), pady=5)
+
+        ttk.Label(purchase_frame, text="游戏优惠券代码:").grid(row=2, column=0, sticky=tk.W, pady=5)
+        self.coupon_var = tk.StringVar(value="")
+        coupon_entry = ttk.Entry(purchase_frame, textvariable=self.coupon_var, width=30)
+        coupon_entry.grid(row=2, column=1, sticky=tk.W, padx=(10, 0), pady=5)
+
+        # ========== 操作按钮 ==========
+        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_purchase, width=18)
+        self.start_btn.pack(side=tk.LEFT, padx=(0, 10))
+
+        self.stop_btn = ttk.Button(button_frame, text="停止", command=self.stop_purchase, 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))
+
+        # ========== 执行状态 ==========
+        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))
+        ttk.Label(progress_frame, text="进度:", font=("微软雅黑", 9)).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(self, message, level="info"):
+        def _append():
+            ts = datetime.now().strftime("%H:%M:%S")
+            self.result_text.insert(tk.END, f"[{ts}] ", "timestamp")
+            self.result_text.insert(tk.END, f"{message}\n", level)
+            self.result_text.see(tk.END)
+        self.root.after(0, _append)
+
+    def set_status(self, text, color="black"):
+        self.root.after(0, lambda: self.status_label.config(text=text, foreground=color))
+
+    def set_progress(self, current, total):
+        pct = int(current / total * 100) if total else 0
+        self.root.after(0, lambda: self.progress_var.set(f"{current}/{total} ({pct}%)"))
+
+    # ================= 业务逻辑 =================
+    def parse_accounts(self):
+        raw = self.account_list_text.get("1.0", tk.END).strip()
+        accounts = []
+        for line in raw.splitlines():
+            line = line.strip()
+            if not line:
+                continue
+            if "|" in line:
+                parts = [p.strip() for p in line.split("|", 1)]
+                email, password = parts[0], parts[1]
+            else:
+                email, password = line, ""
+            accounts.append((email, password))
+        return accounts
+
+    def publish_task(self, content):
+        url = f"{BASE_URL.rstrip('/')}/publish/{CHANNEL}/{TIMEOUT}"
+        try:
+            resp = requests.post(url, json=content, timeout=10)
+            data = resp.json()
+            if data.get("success"):
+                return True, data.get("taskId", "")
+            return False, data.get("error", f"HTTP {resp.status_code}")
+        except Exception as e:
+            return False, str(e)
+
+    def start_purchase(self):
+        if self.running:
+            messagebox.showwarning("提示", "任务正在执行中")
+            return
+
+        accounts = self.parse_accounts()
+        if not accounts:
+            messagebox.showwarning("提示", "账号列表为空")
+            return
+
+        game_url = self.game_url_var.get().strip()
+        if not game_url:
+            messagebox.showwarning("提示", "请填写游戏购买地址")
+            return
+
+        quantity = self.quantity_var.get().strip() or "1"
+        coupon = self.coupon_var.get().strip()
+
+        self.running = True
+        self.start_btn.config(state="disabled")
+        self.stop_btn.config(state="normal")
+        self.set_status("正在提交...", "blue")
+        self.set_progress(0, len(accounts))
+
+        threading.Thread(
+            target=self._publish_worker,
+            args=(accounts, game_url, quantity, coupon),
+            daemon=True
+        ).start()
+
+    def _publish_worker(self, accounts, game_url, quantity, coupon):
+        total = len(accounts)
+        success = 0
+        fail = 0
+
+        self.log(f"共 {total} 个账号,开始提交任务...", "info")
+
+        for idx, (email, password) in enumerate(accounts, start=1):
+            if not self.running:
+                self.log("用户已停止任务", "warning")
+                break
+
+            content = {
+                "email": email,
+                "password": password,
+                "game_url": game_url,
+                "quantity": quantity,
+                "coupon": coupon,
+            }
+
+            ok, info = self.publish_task(content)
+            if ok:
+                success += 1
+                self.log(f"[{idx}/{total}] 已提交: {email}  ->  {info}", "success")
+            else:
+                fail += 1
+                self.log(f"[{idx}/{total}] 提交失败: {email}  ->  {info}", "error")
+
+            self.set_progress(idx, total)
+
+        self.log(f"全部完成,成功 {success} 条,失败 {fail} 条", "info")
+        self.set_status(f"完成 (成功 {success} / 失败 {fail})", "green")
+        self.running = False
+        self.root.after(0, lambda: self.start_btn.config(state="normal"))
+        self.root.after(0, lambda: self.stop_btn.config(state="disabled"))
+
+    def stop_purchase(self):
+        if not self.running:
+            return
+        self.running = False
+        self.log("正在停止任务...", "warning")
+        self.set_status("已停止", "orange")
+
+    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 = NewToolGUI(root)
+    root.mainloop()