Improve UI cohesion, status bar, and core attack reliability
This commit is contained in:
@@ -26,10 +26,11 @@ class AttackTab(ctk.CTkFrame):
|
||||
|
||||
def __init__(self, parent, proxy_pool: ProxyPool,
|
||||
status_callback: Optional[Callable] = None,
|
||||
attempt_logger=None):
|
||||
attempt_logger=None, app=None):
|
||||
super().__init__(parent, fg_color=CyberpunkTheme.BG_MEDIUM)
|
||||
self.proxy_pool = proxy_pool
|
||||
self.status_callback = status_callback
|
||||
self.app = app
|
||||
self.orchestrator = AttackOrchestrator(
|
||||
proxy_pool, logger_instance=attempt_logger)
|
||||
self._build_ui()
|
||||
@@ -43,14 +44,16 @@ class AttackTab(ctk.CTkFrame):
|
||||
# ── Build ──────────────────────────────────────────────────────────────────
|
||||
|
||||
def _build_ui(self):
|
||||
ctk.CTkLabel(self, text="[ ATTACK TERMINAL ]",
|
||||
font=("Consolas", 18, "bold"),
|
||||
text_color=CyberpunkTheme.PRIMARY).pack(pady=(15, 2))
|
||||
ctk.CTkLabel(self,
|
||||
text="Multi-threaded · Proxy rotation · GPU-optimised wordlist · Any site",
|
||||
font=("Consolas", 10),
|
||||
text_color=CyberpunkTheme.TEXT_SECONDARY).pack(pady=(0, 10))
|
||||
CyberpunkTheme.create_tab_header(
|
||||
self, "03", "[ ATTACK TERMINAL ]",
|
||||
"Multi-threaded login attempts with proxy rotation against any target URL",
|
||||
)
|
||||
CyberpunkTheme.create_hint_bar(
|
||||
self,
|
||||
"Set target URL + email → confirm readiness below → START when wordlist and proxies are loaded",
|
||||
)
|
||||
|
||||
self._build_readiness_bar()
|
||||
self._build_target_bar()
|
||||
self._build_speed_panel()
|
||||
self._build_stats_panel()
|
||||
@@ -58,6 +61,62 @@ class AttackTab(ctk.CTkFrame):
|
||||
self._build_control_buttons()
|
||||
self._build_live_log()
|
||||
self._update_periodic()
|
||||
self._update_readiness()
|
||||
|
||||
def _build_readiness_bar(self):
|
||||
"""At-a-glance checklist so the user knows what's missing before START."""
|
||||
bar = ctk.CTkFrame(
|
||||
self, fg_color=CyberpunkTheme.BG_DARK,
|
||||
border_width=1, border_color=CyberpunkTheme.BORDER,
|
||||
)
|
||||
bar.pack(fill="x", padx=15, pady=(0, 8))
|
||||
inner = ctk.CTkFrame(bar, fg_color="transparent")
|
||||
inner.pack(fill="x", padx=12, pady=8)
|
||||
|
||||
ctk.CTkLabel(
|
||||
inner, text="READINESS",
|
||||
font=("Consolas", 10, "bold"),
|
||||
text_color=CyberpunkTheme.TERTIARY,
|
||||
width=80, anchor="w",
|
||||
).pack(side="left")
|
||||
|
||||
def _chip(parent):
|
||||
lbl = ctk.CTkLabel(
|
||||
parent, text="—",
|
||||
font=("Consolas", 10, "bold"),
|
||||
text_color=CyberpunkTheme.TEXT_DIM,
|
||||
)
|
||||
lbl.pack(side="left", padx=(0, 16))
|
||||
return lbl
|
||||
|
||||
self.ready_target = _chip(inner)
|
||||
self.ready_wordlist = _chip(inner)
|
||||
self.ready_proxies = _chip(inner)
|
||||
self.ready_overall = _chip(inner)
|
||||
|
||||
def _update_readiness(self):
|
||||
target_ok = bool(self.email_entry.get().strip()) if hasattr(self, "email_entry") else False
|
||||
wl = count_lines(PASSWORDS_FILE)
|
||||
px = self.proxy_pool.available_count
|
||||
|
||||
def _set(lbl, ok: bool, ok_text: str, bad_text: str):
|
||||
lbl.configure(
|
||||
text=ok_text if ok else bad_text,
|
||||
text_color=CyberpunkTheme.SUCCESS if ok else CyberpunkTheme.WARNING,
|
||||
)
|
||||
|
||||
_set(self.ready_target, target_ok,
|
||||
"✓ TARGET SET", "✗ NEED EMAIL")
|
||||
_set(self.ready_wordlist, wl > 0,
|
||||
f"✓ WORDLIST ({wl:,})", "✗ NO WORDLIST")
|
||||
_set(self.ready_proxies, px > 0,
|
||||
f"✓ PROXIES ({px})", "○ NO PROXIES (optional)")
|
||||
|
||||
all_core = target_ok and wl > 0
|
||||
self.ready_overall.configure(
|
||||
text="✓ READY TO START" if all_core else "✗ NOT READY",
|
||||
text_color=CyberpunkTheme.SUCCESS if all_core else CyberpunkTheme.ERROR,
|
||||
)
|
||||
|
||||
# ── Target bar (URL + username + counters) ────────────────────────────────
|
||||
|
||||
@@ -119,6 +178,7 @@ class AttackTab(ctk.CTkFrame):
|
||||
text_color=CyberpunkTheme.TEXT_PRIMARY, font=("Consolas", 12), width=310)
|
||||
self.email_entry.pack(side="left", padx=(0, 20))
|
||||
CyberpunkTheme.apply_focus_glow(self.email_entry)
|
||||
self.email_entry.bind("<KeyRelease>", lambda _e: self._update_readiness())
|
||||
|
||||
self.pwd_count_label = ctk.CTkLabel(
|
||||
row2, text="Wordlist: 0",
|
||||
@@ -364,6 +424,9 @@ class AttackTab(ctk.CTkFrame):
|
||||
self.orchestrator.configure(username, passwords, site_cfg)
|
||||
self.orchestrator.start()
|
||||
|
||||
if self.app:
|
||||
self.app.set_attack_state("RUNNING")
|
||||
|
||||
self.start_btn.configure(state="disabled")
|
||||
self.pause_btn.configure(state="normal")
|
||||
self.stop_btn.configure(state="normal")
|
||||
@@ -388,6 +451,8 @@ class AttackTab(ctk.CTkFrame):
|
||||
|
||||
def _on_stop(self):
|
||||
self.orchestrator.stop()
|
||||
if self.app:
|
||||
self.app.set_attack_state("STOPPED")
|
||||
self.start_btn.configure(state="normal")
|
||||
self.pause_btn.configure(state="disabled", text="⏸ PAUSE")
|
||||
self.stop_btn.configure(state="disabled")
|
||||
@@ -463,6 +528,8 @@ class AttackTab(ctk.CTkFrame):
|
||||
self.state_label.configure(
|
||||
text=f"◈ {state.value.upper()}",
|
||||
text_color=colors.get(state, CyberpunkTheme.TEXT_DIM))
|
||||
if self.app:
|
||||
self.app.set_attack_state(state.value.upper())
|
||||
if state in (AttackState.COMPLETED, AttackState.STOPPED):
|
||||
self.start_btn.configure(state="normal")
|
||||
self.pause_btn.configure(state="disabled", text="⏸ PAUSE")
|
||||
@@ -487,4 +554,5 @@ class AttackTab(ctk.CTkFrame):
|
||||
except Exception:
|
||||
pass
|
||||
self.proxy_count_label.configure(text=f"Proxies: {self.proxy_pool.available_count}")
|
||||
self._update_readiness()
|
||||
self.after(2000, self._update_periodic)
|
||||
|
||||
Reference in New Issue
Block a user